/*---------------------------------------------------------------------------*/ static void recv_data(struct unicast_conn *c, const linkaddr_t *from) { struct route_entry *e; linkaddr_t source; uip_len = packetbuf_copyto(&uip_buf[UIP_LLH_LEN]); source.u8[0] = BUF->srcipaddr.u8[2]; source.u8[1] = BUF->srcipaddr.u8[3]; e = route_lookup(&source); if(e == NULL) { route_add(&source, from, 10, 0); } else { route_refresh(e); } /* If we received data via a gateway, we refresh the gateway route. * Note: we refresh OUR gateway route, although we are not sure it forwarded the data. */ if(!uip_ipaddr_maskcmp(&BUF->srcipaddr, &netaddr, &netmask)) { e = route_lookup(&gateway); if(e != NULL) { route_refresh(e); } } PRINTF("uip-over-mesh: %d.%d: recv_data with len %d\n", linkaddr_node_addr.u8[0], linkaddr_node_addr.u8[1], uip_len); tcpip_input(); }
/*---------------------------------------------------------------------------*/ static void send_rrep(struct route_discovery_conn *c, const linkaddr_t *dest) { struct rrep_hdr *rrepmsg; struct route_entry *rt; linkaddr_t saved_dest; linkaddr_copy(&saved_dest, dest); packetbuf_clear(); dest = &saved_dest; rrepmsg = packetbuf_dataptr(); packetbuf_set_datalen(sizeof(struct rrep_hdr)); rrepmsg->hops = 0; linkaddr_copy(&rrepmsg->dest, dest); linkaddr_copy(&rrepmsg->originator, &linkaddr_node_addr); rt = route_lookup(dest); if(rt != NULL) { PRINTF("%d.%d: send_rrep to %d.%d via %d.%d\n", linkaddr_node_addr.u8[0], linkaddr_node_addr.u8[1], dest->u8[0],dest->u8[1], rt->nexthop.u8[0],rt->nexthop.u8[1]); unicast_send(&c->rrepconn, &rt->nexthop); } else { PRINTF("%d.%d: no route for rrep to %d.%d\n", linkaddr_node_addr.u8[0], linkaddr_node_addr.u8[1], dest->u8[0],dest->u8[1]); } }
static uip_ipaddr_t * lookup(uip_ipaddr_t *destipaddr, uip_ipaddr_t *nexthop) { static rimeaddr_t rimeaddr; struct route_entry *route; int i; for(i = 1; i < sizeof(rimeaddr); i++) { rimeaddr.u8[i] = destipaddr->u8[sizeof(*destipaddr) - sizeof(rimeaddr) + i]; } rimeaddr.u8[0] = 0; PRINTF("rimeroute: looking up "); PRINT6ADDR(destipaddr); PRINTF(" with Rime address "); PRINTRIMEADDR((&rimeaddr)); PRINTF("\n"); route = route_lookup(&rimeaddr); if(route == NULL) { process_post(&rimeroute_process, rimeroute_event, &rimeaddr); return NULL; } uip_ip6addr(nexthop, 0xfe80, 0, 0, 0, 0, 0, 0, 0); uip_netif_addr_autoconf_set(nexthop, (uip_lladdr_t *)&route->nexthop); PRINTF("rimeroute: "); PRINT6ADDR(destipaddr); PRINTF(" can be reached via "); PRINT6ADDR(nexthop); PRINTF("\n"); return nexthop; }
/*---------------------------------------------------------------------------*/ static void found_route(struct route_discovery_conn *rdc, const rimeaddr_t *dest) { struct route_entry *rt; struct mesh_conn *c = (struct mesh_conn *) ((char *)rdc - offsetof(struct mesh_conn, route_discovery_conn)); PRINTF("found_route\n"); if(c->queued_data != NULL && rimeaddr_cmp(dest, &c->queued_data_dest)) { queuebuf_to_packetbuf(c->queued_data); queuebuf_free(c->queued_data); c->queued_data = NULL; rt = route_lookup(dest); if(rt != NULL) { multihop_resend(&c->multihop, &rt->R_next_addr); if(c->cb->sent != NULL) { c->cb->sent(c); } } else { if(c->cb->timedout != NULL) { c->cb->timedout(c); } } } }
rimeaddr_t * c_multihop_forward(struct pipe *p, struct stackmodule_i *module) { printf("multihop forward \n"); struct route_entry *rt, *previous_rt; rimeaddr_t *tmpaddr = get_node_addr(module->stack_id, 0, 3); rt = route_lookup(tmpaddr); if (rt == NULL) { return NULL; } else { /*if(clock_time()*1000/CLOCK_SECOND < 50100 && rimeaddr_node_addr.u8[0] == 1) { previous_rt->nexthop.u8[0] = rt->nexthop.u8[0]; previous_rt->cost = rt->cost; } if(clock_time()*1000/CLOCK_SECOND > 50100 && rimeaddr_node_addr.u8[0] == 1 && rt->nexthop.u8[0] == previous_rt->nexthop.u8[0] && previous_rt->cost == rt->cost) { route_remove(rt); rt = route_lookup(tmpaddr); }*/ /*if(clock_time()*1000/CLOCK_SECOND < 50100) { previous_rt->nexthop.u8[0] = rt->nexthop.u8[0]; previous_rt->cost = rt->cost; } if(clock_time()*1000/CLOCK_SECOND > 50100 && rt->nexthop.u8[0] == previous_rt->nexthop.u8[0] && previous_rt->cost == rt->cost) { route_remove(rt); return NULL; }*/ route_refresh(rt); } PRINTF("~c_multihop_forward \n"); return &rt->nexthop; }
/*---------------------------------------------------------------------------*/ static rimeaddr_t * data_packet_forward(struct multihop_conn *multihop, const rimeaddr_t *originator, const rimeaddr_t *dest, const rimeaddr_t *prevhop, uint8_t hops) { struct route_entry *rt; struct mesh_conn *c = (struct mesh_conn *) ((char *)multihop - offsetof(struct mesh_conn, multihop)); rt = route_lookup(dest); if(rt == NULL) { if(c->queued_data != NULL) { queuebuf_free(c->queued_data); } PRINTF("data_packet_forward: queueing data, sending rreq\n"); c->queued_data = queuebuf_new_from_packetbuf(); rimeaddr_copy(&c->queued_data_dest, dest); route_discovery_discover(&c->route_discovery_conn, dest, PACKET_TIMEOUT); return NULL; } else { route_refresh(rt); } return &rt->R_next_addr; }
static int add_route(struct tree_item *root, const char *prefix, const char *route) { int ix, err; /* We cache the route index here so we can avoid route_lookup() * in the prefix_route() routing function. */ ix = route_lookup(&main_rt, (char *)route); if (ix < 0) { LM_CRIT("route name '%s' is not defined\n", route); return -1; } if (ix >= main_rt.entries) { LM_CRIT("route %d > n_entries (%d)\n", ix, main_rt.entries); return -1; } err = tree_item_add(root, prefix, route, ix); if (0 != err) { LM_CRIT("tree_item_add() failed (%d)\n", err); return err; } return 0; }
int pv_set_dlg_ctx(struct sip_msg* msg, pv_param_t *param, int op, pv_value_t *val) { int n; char *rtp; if(param==NULL) return -1; if(val==NULL) n = 0; else n = val->ri; switch(param->pvn.u.isname.name.n) { case 1: _dlg_ctx.flags = n; break; case 2: _dlg_ctx.timeout = n; break; case 3: _dlg_ctx.to_bye = n; break; case 4: if(val->flags&PV_VAL_STR) { if(val->rs.s[val->rs.len]=='\0' && val->rs.len<DLG_TOROUTE_SIZE) { _dlg_ctx.to_route = route_lookup(&main_rt, val->rs.s); strcpy(_dlg_ctx.to_route_name, val->rs.s); } else _dlg_ctx.to_route = 0; } else { if(n!=0) { rtp = int2str(n, NULL); _dlg_ctx.to_route = route_lookup(&main_rt, rtp); strcpy(_dlg_ctx.to_route_name, rtp); } else _dlg_ctx.to_route = 0; } if(_dlg_ctx.to_route <0) _dlg_ctx.to_route = 0; break; default: _dlg_ctx.on = n; break; } return 0; }
void rpc_evr_run(rpc_t *rpc, void *c) { str evr_name = STR_NULL; str evr_data = STR_NULL; int ret = 0; int evr_id = -1; sr_kemi_eng_t *keng = NULL; sip_msg_t *fmsg = NULL; int rtbk = 0; char evr_buf[2]; ret = rpc->scan(c, "s*s", &evr_name.s, &evr_data.s); if(ret<1) { LM_ERR("failed getting the parameters"); rpc->fault(c, 500, "Invalid parameters"); return; } evr_name.len = strlen(evr_name.s); if(ret<2) { evr_buf[0] = '\0'; evr_data.s = evr_buf; evr_data.len = 0; } else { evr_data.len = strlen(evr_data.s); } pv_evr_data = &evr_data; keng = sr_kemi_eng_get(); if(keng==NULL) { evr_id = route_lookup(&event_rt, evr_name.s); if(evr_id == -1) { pv_evr_data = NULL; LM_ERR("event route not found: %.*s\n", evr_name.len, evr_name.s); rpc->fault(c, 500, "Event route not found"); return; } } else { evr_id = -1; } fmsg = faked_msg_next(); rtbk = get_route_type(); set_route_type(LOCAL_ROUTE); if(evr_id>=0) { if(event_rt.rlist[evr_id]!=NULL) { run_top_route(event_rt.rlist[evr_id], fmsg, 0); } else { LM_WARN("empty event route block [%.*s]\n", evr_name.len, evr_name.s); } } else { if(sr_kemi_route(keng, fmsg, EVENT_ROUTE, &evr_name, &evr_data)<0) { LM_ERR("error running event route kemi callback\n"); } } set_route_type(rtbk); pv_evr_data = NULL; }
/*! * lookup tls event routes */ void tls_lookup_event_routes(void) { _tls_evrt_connection_out=route_lookup(&event_rt, "tls:connection-out"); if (_tls_evrt_connection_out>=0 && event_rt.rlist[_tls_evrt_connection_out]==0) _tls_evrt_connection_out=-1; /* disable */ if(_tls_evrt_connection_out!=-1) forward_set_send_info(1); }
/*! Check if a route block exists - only request routes */ static int w_check_route_exists(struct sip_msg *msg, char *route) { if (route_lookup(&main_rt, route)<0) { /* not found */ return -1; } return 1; }
/*---------------------------------------------------------------------------*/ static void rrep_packet_received(struct unicast_conn *uc, const rimeaddr_t *from) { struct rrep_hdr *msg = packetbuf_dataptr(); struct route_entry *rt; rimeaddr_t dest; struct route_discovery_conn *c = (struct route_discovery_conn *) ((char *)uc - offsetof(struct route_discovery_conn, rrepconn)); PRINTF("%d.%d: rrep_packet_received from %d.%d towards %d.%d len %d\n", rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1], from->u8[0],from->u8[1], msg->dest.u8[0],msg->dest.u8[1], packetbuf_datalen()); PRINTF("from %d.%d hops %d rssi %d lqi %d\n", from->u8[0], from->u8[1], msg->hops, packetbuf_attr(PACKETBUF_ATTR_RSSI), packetbuf_attr(PACKETBUF_ATTR_LINK_QUALITY)); insert_route(&msg->originator, from, msg->hops); if(rimeaddr_cmp(&msg->dest, &rimeaddr_node_addr)) { PRINTF("rrep for us!\n"); rrep_pending = 0; ctimer_stop(&c->t); if(c->cb->new_route) { rimeaddr_t originator; /* If the callback modifies the packet, the originator address will be lost. Therefore, we need to copy it into a local variable before calling the callback. */ rimeaddr_copy(&originator, &msg->originator); c->cb->new_route(c, &originator); } } else { rimeaddr_copy(&dest, &msg->dest); rt = route_lookup(&msg->dest); if(rt != NULL) { PRINTF("forwarding to %d.%d\n", rt->nexthop.u8[0], rt->nexthop.u8[1]); msg->hops++; unicast_send(&c->rrepconn, &rt->nexthop); } else { PRINTF("%d.%d: no route to %d.%d\n", rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1], msg->dest.u8[0], msg->dest.u8[1]); } } }
void service_dial(struct service *sv, const uint8_t uid[20]) { if(sv->state != STATE_IDLE) { WARN("Bad state to dial (%d)", sv->state); return; } sv->state = STATE_LOOKUP; memcpy(sv->dstid, uid, 20); route_lookup(sv->table, sv->srcid, sv->dstid, &sv->lookup); struct itimerspec its = { { 1, 0 }, { 1, 0 } }; int res = timerfd_settime(sv->timerfd, 0, &its, NULL); assert(res == 0); lookup_handler(sv); }
static void wsconn_run_route(ws_connection_t *wsc) { int rt, backup_rt; struct run_act_ctx ctx; sip_msg_t *fmsg; sr_kemi_eng_t *keng = NULL; str evrtname = str_init("websocket:closed"); LM_DBG("wsconn_run_route event_route[websocket:closed]\n"); rt = route_lookup(&event_rt, evrtname.s); if (rt < 0 || event_rt.rlist[rt] == NULL) { if(ws_event_callback.len<=0 || ws_event_callback.s==NULL) { LM_DBG("event route does not exist"); return; } keng = sr_kemi_eng_get(); if(keng==NULL) { LM_DBG("event route callback engine does not exist"); return; } else { rt = -1; } } if (faked_msg_init() < 0) { LM_ERR("faked_msg_init() failed\n"); return; } fmsg = faked_msg_next(); wsc->rcv.proto_reserved1 = wsc->id; fmsg->rcv = wsc->rcv; backup_rt = get_route_type(); set_route_type(EVENT_ROUTE); init_run_actions_ctx(&ctx); if(rt<0) { /* kemi script event route callback */ if(keng && keng->froute(fmsg, EVENT_ROUTE, &ws_event_callback, &evrtname)<0) { LM_ERR("error running event route kemi callback\n"); } } else { /* native cfg event route */ run_top_route(event_rt.rlist[rt], fmsg, 0); } set_route_type(backup_rt); }
/*---------------------------------------------------------------------------*/ static rimeaddr_t * data_packet_forward(struct multihop_conn *multihop, const rimeaddr_t *originator, const rimeaddr_t *dest, const rimeaddr_t *prevhop, uint8_t hops) { struct route_entry *rt; rt = route_lookup(dest); if(rt == NULL) { return NULL; } return &rt->nexthop; }
/*! Check if a route block exists - only request routes */ static int w_check_route_exists(struct sip_msg *msg, char *route) { str s; if (fixup_get_svalue(msg, (gparam_p) route, &s) != 0) { LM_ERR("invalid route parameter\n"); return -1; } if (route_lookup(&main_rt, s.s)<0) { /* not found */ return -1; } return 1; }
/*! Run a request route block if it exists */ static int w_route_exists(struct sip_msg *msg, char *route) { struct run_act_ctx ctx; int newroute, backup_rt, ret; newroute = route_lookup(&main_rt, route); if (newroute<0) { return -1; } backup_rt = get_route_type(); set_route_type(REQUEST_ROUTE); init_run_actions_ctx(&ctx); ret = run_top_route(main_rt.rlist[newroute], msg, &ctx); set_route_type(backup_rt); return ret; }
/*---------------------------------------------------------------------------*/ static void new_route(struct route_discovery_conn *c, const linkaddr_t *to) { struct route_entry *rt; if(queued_packet) { PRINTF("uip-over-mesh: new route, sending queued packet\n"); queuebuf_to_packetbuf(queued_packet); queuebuf_free(queued_packet); queued_packet = NULL; rt = route_lookup(&queued_receiver); if(rt) { route_decay(rt); send_data(&queued_receiver); } } }
/*---------------------------------------------------------------------------*/ static void data_packet_received(struct multihop_conn *multihop, const rimeaddr_t *from, const rimeaddr_t *prevhop, uint8_t hops) { struct mesh_conn *c = (struct mesh_conn *) ((char *)multihop - offsetof(struct mesh_conn, multihop)); struct route_entry *rt; /* Refresh the route when we hear a packet from a neighbor. */ rt = route_lookup(from); if(rt != NULL) { route_refresh(rt); } if(c->cb->recv) { c->cb->recv(c, from, hops); } }
int dlg_set_toroute(struct dlg_cell *dlg, str *route) { if(dlg==NULL || route==NULL || route->len<=0) return 0; if(dlg->toroute_name.s!=NULL) { shm_free(dlg->toroute_name.s); dlg->toroute_name.s = NULL; dlg->toroute_name.len = 0; } dlg->toroute_name.s = (char*)shm_malloc((route->len+1)*sizeof(char)); if(dlg->toroute_name.s==NULL) { LM_ERR("no more shared memory\n"); return -1; } memcpy(dlg->toroute_name.s, route->s, route->len); dlg->toroute_name.len = route->len; dlg->toroute_name.s[dlg->toroute_name.len] = '\0'; dlg->toroute = route_lookup(&main_rt, dlg->toroute_name.s); return 0; }
/*---------------------------------------------------------------------------*/ static rimeaddr_t * data_packet_forward(struct multihop_conn *multihop, const rimeaddr_t *originator, const rimeaddr_t *dest, const rimeaddr_t *prevhop, uint8_t hops) { struct route_entry *rt; struct mesh_conn *c = (struct mesh_conn *) ((char *)multihop - offsetof(struct mesh_conn, multihop)); rt = route_lookup(dest); if(rt == NULL) { route_discovery_discover(&c->route_discovery_conn, dest, PACKET_TIMEOUT); return NULL; } else { route_refresh(rt); } return &rt->nexthop; }
/*---------------------------------------------------------------------------*/ int route_add(const rimeaddr_t *dest, const rimeaddr_t *nexthop, uint8_t cost, uint8_t seqno) { struct route_entry *e; /* Avoid inserting duplicate entries. */ e = route_lookup(dest); if(e != NULL && rimeaddr_cmp(&e->nexthop, nexthop)) { list_remove(route_table, e); } else { /* Allocate a new entry or reuse the oldest entry with highest cost. */ e = memb_alloc(&route_mem); if(e == NULL) { /* Remove oldest entry. XXX */ e = list_chop(route_table); PRINTF("route_add: removing entry to %d.%d with nexthop %d.%d and cost %d\n", e->dest.u8[0], e->dest.u8[1], e->nexthop.u8[0], e->nexthop.u8[1], e->cost); } } rimeaddr_copy(&e->dest, dest); rimeaddr_copy(&e->nexthop, nexthop); e->cost = cost; e->seqno = seqno; e->time = 0; e->decay = 0; /* New entry goes first. */ list_push(route_table, e); PRINTF("route_add: new entry to %d.%d with nexthop %d.%d and cost %d\n", e->dest.u8[0], e->dest.u8[1], e->nexthop.u8[0], e->nexthop.u8[1], e->cost); return 0; }
int send_to_script(pv_value_t* val, jsonrpc_req_cmd_t* req_cmd) { if(!(req_cmd)) return -1; if(req_cmd->route.len <= 0) return -1; jsonrpc_result_pv.setf(req_cmd->msg, &jsonrpc_result_pv.pvp, (int)EQ_T, val); int n = route_lookup(&main_rt, req_cmd->route.s); if(n<0) { ERR("no such route: %s\n", req_cmd->route.s); return -1; } struct action* route = main_rt.rlist[n]; if(tmb.t_continue(req_cmd->t_hash, req_cmd->t_label, route)<0) { ERR("Failed to resume transaction\n"); return -1; } return 0; }
/*! Run a request route block if it exists */ static int w_route_exists(struct sip_msg *msg, char *route) { struct run_act_ctx ctx; int newroute, ret; str s; if (fixup_get_svalue(msg, (gparam_p) route, &s) != 0) { LM_ERR("invalid route parameter\n"); return -1; } newroute = route_lookup(&main_rt, s.s); if (newroute<0) { return -1; } init_run_actions_ctx(&ctx); ret=run_actions(&ctx, main_rt.rlist[newroute], msg); if (ctx.run_flags & EXIT_R_F) { return 0; } return ret; }
static int mod_init(void) { if (init_sl_stats() < 0) { ERR("init_sl_stats failed\n"); return -1; } if (sl_register_kstats()<0) { ERR("init k stats failed\n"); return -1; } /* if SL loaded, filter ACKs on beginning */ if (register_script_cb( sl_filter_ACK, PRE_SCRIPT_CB|REQUEST_CB, 0 )<0) { ERR("Failed to install SCRIPT callback\n"); return -1; } if(sl_startup()<0) { ERR("Failed to do startup tasks\n"); return -1; } if(sl_bind_tm!=0) { if(load_tm_api(&tmb)==-1) { LM_INFO("could not bind tm module - only stateless mode" " available\n"); sl_bind_tm=0; } } _sl_filtered_ack_route=route_lookup(&event_rt, "sl:filtered-ack"); if (_sl_filtered_ack_route>=0 && event_rt.rlist[_sl_filtered_ack_route]==0) _sl_filtered_ack_route=-1; /* disable */ return 0; }
int evrexec_param(modparam_t type, void *val) { param_t* params_list = NULL; param_hooks_t phooks; param_t *pit=NULL; evrexec_task_t *it; evrexec_task_t tmp; sr_kemi_eng_t *keng = NULL; str s; if(val==NULL) return -1; s.s = (char*)val; s.len = strlen(s.s); if(s.s[s.len-1]==';') s.len--; if (parse_params(&s, CLASS_ANY, &phooks, ¶ms_list)<0) return -1; memset(&tmp, 0, sizeof(evrexec_task_t)); for (pit = params_list; pit; pit=pit->next) { if (pit->name.len==4 && strncasecmp(pit->name.s, "name", 4)==0) { tmp.ename = pit->body; } else if(pit->name.len==4 && strncasecmp(pit->name.s, "wait", 4)==0) { if(tmp.wait==0) { if (str2int(&pit->body, &tmp.wait) < 0) { LM_ERR("invalid wait: %.*s\n", pit->body.len, pit->body.s); return -1; } } } else if(pit->name.len==7 && strncasecmp(pit->name.s, "workers", 7)==0) { if(tmp.workers==0) { if (str2int(&pit->body, &tmp.workers) < 0) { LM_ERR("invalid workers: %.*s\n", pit->body.len, pit->body.s); return -1; } } } else { LM_ERR("invalid attribute: %.*s\n", pit->body.len, pit->body.s); return -1; } } if(tmp.ename.s==NULL || tmp.ename.len<=0) { LM_ERR("missing or invalid name attribute\n"); free_params(params_list); return -1; } /* set '\0' at the end of route name */ tmp.ename.s[tmp.ename.len] = '\0'; keng = sr_kemi_eng_get(); if(keng==NULL) { tmp.rtid = route_lookup(&event_rt, tmp.ename.s); if(tmp.rtid == -1) { LM_ERR("event route not found: %.*s\n", tmp.ename.len, tmp.ename.s); free_params(params_list); return -1; } } else { tmp.rtid = -1; } it = (evrexec_task_t*)pkg_malloc(sizeof(evrexec_task_t)); if(it==0) { LM_ERR("no more pkg memory\n"); free_params(params_list); return -1; } memcpy(it, &tmp, sizeof(evrexec_task_t)); if(it->workers==0) it->workers=1; it->next = _evrexec_list; _evrexec_list = it; free_params(params_list); return 0; }
static int mod_init(void) { unsigned int n; if(dlg_ka_interval!=0 && dlg_ka_interval<30) { LM_ERR("ka interval too low (%d), has to be at least 30\n", dlg_ka_interval); return -1; } dlg_event_rt[DLG_EVENTRT_START] = route_lookup(&event_rt, "dialog:start"); dlg_event_rt[DLG_EVENTRT_END] = route_lookup(&event_rt, "dialog:end"); dlg_event_rt[DLG_EVENTRT_FAILED] = route_lookup(&event_rt, "dialog:failed"); #ifdef STATISTICS /* register statistics */ if (register_module_stats( exports.name, mod_stats)!=0 ) { LM_ERR("failed to register %s statistics\n", exports.name); return -1; } #endif if(register_mi_mod(exports.name, mi_cmds)!=0) { LM_ERR("failed to register MI commands\n"); return -1; } if (rpc_register_array(rpc_methods)!=0) { LM_ERR("failed to register RPC commands\n"); return -1; } if(faked_msg_init()<0) return -1; if(dlg_bridge_init_hdrs()<0) return -1; /* param checkings */ if (dlg_flag==-1) { LM_ERR("no dlg flag set!!\n"); return -1; } else if (dlg_flag>MAX_FLAG) { LM_ERR("invalid dlg flag %d!!\n",dlg_flag); return -1; } if (rr_param==0 || rr_param[0]==0) { LM_ERR("empty rr_param!!\n"); return -1; } else if (strlen(rr_param)>MAX_DLG_RR_PARAM_NAME) { LM_ERR("rr_param too long (max=%d)!!\n", MAX_DLG_RR_PARAM_NAME); return -1; } if (timeout_spec.s) { if ( pv_parse_spec(&timeout_spec, &timeout_avp)==0 && (timeout_avp.type!=PVT_AVP)){ LM_ERR("malformed or non AVP timeout " "AVP definition in '%.*s'\n", timeout_spec.len,timeout_spec.s); return -1; } } if (default_timeout<=0) { LM_ERR("0 default_timeout not accepted!!\n"); return -1; } if (ruri_pvar_param.s==NULL || ruri_pvar_param.len<=0) { LM_ERR("invalid r-uri PV string\n"); return -1; } if(pv_parse_format(&ruri_pvar_param, &ruri_param_model) < 0 || ruri_param_model==NULL) { LM_ERR("malformed r-uri PV string: %s\n", ruri_pvar_param.s); return -1; } if (initial_cbs_inscript != 0 && initial_cbs_inscript != 1) { LM_ERR("invalid parameter for running initial callbacks in-script" " (must be either 0 or 1)\n"); return -1; } if (seq_match_mode!=SEQ_MATCH_NO_ID && seq_match_mode!=SEQ_MATCH_FALLBACK && seq_match_mode!=SEQ_MATCH_STRICT_ID ) { LM_ERR("invalid value %d for seq_match_mode param!!\n",seq_match_mode); return -1; } if (detect_spirals != 0 && detect_spirals != 1) { LM_ERR("invalid value %d for detect_spirals param!!\n",detect_spirals); return -1; } if (dlg_timeout_noreset != 0 && dlg_timeout_noreset != 1) { LM_ERR("invalid value %d for timeout_noreset param!!\n", dlg_timeout_noreset); return -1; } /* if statistics are disabled, prevent their registration to core */ if (dlg_enable_stats==0) exports.stats = 0; /* create profile hashes */ if (add_profile_definitions( profiles_nv_s, 0)!=0 ) { LM_ERR("failed to add profiles without value\n"); return -1; } if (add_profile_definitions( profiles_wv_s, 1)!=0 ) { LM_ERR("failed to add profiles with value\n"); return -1; } /* load the TM API */ if (load_tm_api(&d_tmb)!=0) { LM_ERR("can't load TM API\n"); return -1; } /* load RR API also */ if (load_rr_api(&d_rrb)!=0) { LM_ERR("can't load RR API\n"); return -1; } /* register callbacks*/ /* listen for all incoming requests */ if ( d_tmb.register_tmcb( 0, 0, TMCB_REQUEST_IN, dlg_onreq, 0, 0 ) <=0 ) { LM_ERR("cannot register TMCB_REQUEST_IN callback\n"); return -1; } /* listen for all routed requests */ if ( d_rrb.register_rrcb( dlg_onroute, 0 ) <0 ) { LM_ERR("cannot register RR callback\n"); return -1; } if (register_script_cb( profile_cleanup, POST_SCRIPT_CB|REQUEST_CB,0)<0) { LM_ERR("cannot register script callback"); return -1; } if (register_script_cb(dlg_cfg_cb, PRE_SCRIPT_CB|REQUEST_CB,0)<0) { LM_ERR("cannot register pre-script ctx callback\n"); return -1; } if (register_script_cb(dlg_cfg_cb, POST_SCRIPT_CB|REQUEST_CB,0)<0) { LM_ERR("cannot register post-script ctx callback\n"); return -1; } if (register_script_cb( spiral_detect_reset, POST_SCRIPT_CB|REQUEST_CB,0)<0) { LM_ERR("cannot register req pre-script spiral detection reset callback\n"); return -1; } if(dlg_timer_procs<=0) { if ( register_timer( dlg_timer_routine, 0, 1)<0 ) { LM_ERR("failed to register timer \n"); return -1; } } else { register_sync_timers(1); } /* init handlers */ init_dlg_handlers( rr_param, dlg_flag, timeout_spec.s?&timeout_avp:0, default_timeout, seq_match_mode); /* init timer */ if (init_dlg_timer(dlg_ontimeout)!=0) { LM_ERR("cannot init timer list\n"); return -1; } /* sanitize dlg_hash_zie */ if (dlg_hash_size < 1){ LM_WARN("hash_size is smaller " "then 1 -> rounding from %d to 1\n", dlg_hash_size); dlg_hash_size = 1; } /* initialized the hash table */ for( n=0 ; n<(8*sizeof(n)) ; n++) { if (dlg_hash_size==(1<<n)) break; if (n && dlg_hash_size<(1<<n)) { LM_WARN("hash_size is not a power " "of 2 as it should be -> rounding from %d to %d\n", dlg_hash_size, 1<<(n-1)); dlg_hash_size = 1<<(n-1); } } if ( init_dlg_table(dlg_hash_size)<0 ) { LM_ERR("failed to create hash table\n"); return -1; } /* if a database should be used to store the dialogs' information */ dlg_db_mode = dlg_db_mode_param; if (dlg_db_mode==DB_MODE_NONE) { db_url.s = 0; db_url.len = 0; } else { if (dlg_db_mode!=DB_MODE_REALTIME && dlg_db_mode!=DB_MODE_DELAYED && dlg_db_mode!=DB_MODE_SHUTDOWN ) { LM_ERR("unsupported db_mode %d\n", dlg_db_mode); return -1; } if ( !db_url.s || db_url.len==0 ) { LM_ERR("db_url not configured for db_mode %d\n", dlg_db_mode); return -1; } if (init_dlg_db(&db_url, dlg_hash_size, db_update_period,db_fetch_rows)!=0) { LM_ERR("failed to initialize the DB support\n"); return -1; } run_load_callbacks(); } destroy_dlg_callbacks( DLGCB_LOADED ); /* timer process to send keep alive requests */ if(dlg_ka_timer>0 && dlg_ka_interval>0) register_sync_timers(1); /* timer process to clean old unconfirmed dialogs */ register_sync_timers(1); return 0; }
static int child_init(int rank) { struct sip_msg *fmsg; struct run_act_ctx ctx; int rtb, rt; int i; sr_kemi_eng_t *keng = NULL; str evname = str_init("htable:mod-init"); LM_DBG("rank is (%d)\n", rank); if(rank==PROC_MAIN) { if(ht_timer_procs>0) { for(i=0; i<ht_timer_procs; i++) { if(fork_sync_timer(PROC_TIMER, "HTable Timer", 1 /*socks flag*/, ht_timer, (void*)(long)i, ht_timer_interval)<0) { LM_ERR("failed to start timer routine as process\n"); return -1; /* error */ } } } } if (rank!=PROC_INIT) return 0; rt = -1; if(ht_event_callback.s==NULL || ht_event_callback.len<=0) { rt = route_lookup(&event_rt, evname.s); if(rt<0 || event_rt.rlist[rt]==NULL) { rt = -1; } } else { keng = sr_kemi_eng_get(); if(keng==NULL) { LM_DBG("event callback (%s) set, but no cfg engine\n", ht_event_callback.s); goto done; } } if(rt>=0 || ht_event_callback.len>0) { LM_DBG("executing event_route[%s] (%d)\n", evname.s, rt); if(faked_msg_init()<0) return -1; fmsg = faked_msg_next(); rtb = get_route_type(); set_route_type(REQUEST_ROUTE); init_run_actions_ctx(&ctx); if(rt>=0) { run_top_route(event_rt.rlist[rt], fmsg, &ctx); } else { if(keng!=NULL) { if(keng->froute(fmsg, EVENT_ROUTE, &ht_event_callback, &evname)<0) { LM_ERR("error running event route kemi callback\n"); return -1; } } } set_route_type(rtb); if(ctx.run_flags&DROP_R_F) { LM_ERR("exit due to 'drop' in event route\n"); return -1; } } done: return 0; }
rt_data_t* dr_load_routing_info( db_func_t *dr_dbf, db1_con_t* db_hdl, str *drd_table, str *drl_table, str* drr_table ) { int int_vals[4]; char * str_vals[5]; str tmp; db_key_t columns[7]; db1_res_t* res; db_row_t* row; rt_info_t *ri; rt_data_t *rdata; tmrec_t *time_rec; unsigned int id; str s_id; int i,n; res = 0; ri = 0; rdata = 0; /* init new data structure */ if ( (rdata=build_rt_data())==0 ) { LM_ERR("failed to build rdata\n"); goto error; } /* read the destinations */ if (dr_dbf->use_table( db_hdl, drd_table) < 0) { LM_ERR("cannot select table \"%.*s\"\n", drd_table->len,drd_table->s); goto error; } columns[0] = &dst_id_drd_col; columns[1] = &address_drd_col; columns[2] = &strip_drd_col; columns[3] = &prefix_drd_col; columns[4] = &type_drd_col; columns[5] = &attrs_drd_col; if (DB_CAPABILITY(*dr_dbf, DB_CAP_FETCH)) { if ( dr_dbf->query( db_hdl, 0, 0, 0, columns, 0, 6, 0, 0 ) < 0) { LM_ERR("DB query failed\n"); goto error; } if(dr_dbf->fetch_result(db_hdl, &res, dr_fetch_rows)<0) { LM_ERR("Error fetching rows\n"); goto error; } } else { if ( dr_dbf->query( db_hdl, 0, 0, 0, columns, 0, 6, 0, &res) < 0) { LM_ERR("DB query failed\n"); goto error; } } if (RES_ROW_N(res) == 0) { LM_WARN("table \"%.*s\" empty\n", drd_table->len,drd_table->s ); } LM_DBG("%d records found in %.*s\n", RES_ROW_N(res), drd_table->len,drd_table->s); n = 0; do { for(i=0; i < RES_ROW_N(res); i++) { row = RES_ROWS(res) + i; /* DST_ID column */ check_val( ROW_VALUES(row), DB1_INT, 1, 0); int_vals[0] = VAL_INT (ROW_VALUES(row)); /* ADDRESS column */ check_val( ROW_VALUES(row)+1, DB1_STRING, 1, 1); str_vals[0] = (char*)VAL_STRING(ROW_VALUES(row)+1); /* STRIP column */ check_val( ROW_VALUES(row)+2, DB1_INT, 1, 0); int_vals[1] = VAL_INT (ROW_VALUES(row)+2); /* PREFIX column */ check_val( ROW_VALUES(row)+3, DB1_STRING, 0, 0); str_vals[1] = (char*)VAL_STRING(ROW_VALUES(row)+3); /* TYPE column */ check_val( ROW_VALUES(row)+4, DB1_INT, 1, 0); int_vals[2] = VAL_INT(ROW_VALUES(row)+4); /* ATTRS column */ check_val( ROW_VALUES(row)+5, DB1_STRING, 0, 0); str_vals[2] = (char*)VAL_STRING(ROW_VALUES(row)+5); /* add the destinaton definition in */ if ( add_dst( rdata, int_vals[0], str_vals[0], int_vals[1], str_vals[1], int_vals[2], str_vals[2])<0 ) { LM_ERR("failed to add destination id %d -> skipping\n", int_vals[0]); continue; } n++; } if (DB_CAPABILITY(*dr_dbf, DB_CAP_FETCH)) { if(dr_dbf->fetch_result(db_hdl, &res, dr_fetch_rows)<0) { LM_ERR( "fetching rows (1)\n"); goto error; } } else { break; } } while(RES_ROW_N(res)>0); dr_dbf->free_result(db_hdl, res); res = 0; if (n==0) { LM_WARN("no valid " "destinations set -> ignoring the routing rules\n"); return rdata; } /* read the gw lists, if any */ if (dr_dbf->use_table( db_hdl, drl_table) < 0) { LM_ERR("cannot select table \"%.*s\"\n", drl_table->len,drl_table->s); goto error; } columns[0] = &id_drl_col; columns[1] = &gwlist_drl_col; if (DB_CAPABILITY(*dr_dbf, DB_CAP_FETCH)) { if ( dr_dbf->query( db_hdl, 0, 0, 0, columns, 0, 2, 0, 0 ) < 0) { LM_ERR("DB query failed\n"); goto error; } if(dr_dbf->fetch_result(db_hdl, &res, dr_fetch_rows)<0) { LM_ERR("Error fetching rows\n"); goto error; } } else { if ( dr_dbf->query( db_hdl, 0, 0, 0, columns, 0, 2, 0, &res) < 0) { LM_ERR("DB query failed\n"); goto error; } } if (RES_ROW_N(res) == 0) { LM_DBG("table \"%.*s\" empty\n", drl_table->len,drl_table->s ); } else { LM_DBG("%d records found in %.*s\n", RES_ROW_N(res), drl_table->len,drl_table->s); do { for(i=0; i < RES_ROW_N(res); i++) { row = RES_ROWS(res) + i; /* ID column */ check_val( ROW_VALUES(row), DB1_INT, 1, 0); int_vals[0] = VAL_INT (ROW_VALUES(row)); /* GWLIST column */ check_val( ROW_VALUES(row)+1, DB1_STRING, 1, 1); str_vals[0] = (char*)VAL_STRING(ROW_VALUES(row)+1); if (add_tmp_gw_list(int_vals[0], str_vals[0])!=0) { LM_ERR("failed to add temporary GW list\n"); goto error; } } if (DB_CAPABILITY(*dr_dbf, DB_CAP_FETCH)) { if(dr_dbf->fetch_result(db_hdl, &res, dr_fetch_rows)<0) { LM_ERR( "fetching rows (1)\n"); goto error; } } else { break; } } while(RES_ROW_N(res)>0); } dr_dbf->free_result(db_hdl, res); res = 0; /* read the routing rules */ if (dr_dbf->use_table( db_hdl, drr_table) < 0) { LM_ERR("cannot select table \"%.*s\"\n", drr_table->len, drr_table->s); goto error; } columns[0] = &rule_id_drr_col; columns[1] = &group_drr_col; columns[2] = &prefix_drr_col; columns[3] = &time_drr_col; columns[4] = &priority_drr_col; columns[5] = &routeid_drr_col; columns[6] = &dstlist_drr_col; if (DB_CAPABILITY(*dr_dbf, DB_CAP_FETCH)) { if ( dr_dbf->query( db_hdl, 0, 0, 0, columns, 0, 7, 0, 0) < 0) { LM_ERR("DB query failed\n"); goto error; } if(dr_dbf->fetch_result(db_hdl, &res, dr_fetch_rows)<0) { LM_ERR("Error fetching rows\n"); goto error; } } else { if ( dr_dbf->query( db_hdl, 0, 0, 0, columns, 0, 7, 0, &res) < 0) { LM_ERR("DB query failed\n"); goto error; } } if (RES_ROW_N(res) == 0) { LM_WARN("table \"%.*s\" is empty\n", drr_table->len, drr_table->s); } LM_DBG("%d records found in %.*s\n", RES_ROW_N(res), drr_table->len, drr_table->s); n = 0; do { for(i=0; i < RES_ROW_N(res); i++) { row = RES_ROWS(res) + i; /* RULE_ID column */ check_val( ROW_VALUES(row), DB1_INT, 1, 0); int_vals[0] = VAL_INT (ROW_VALUES(row)); /* GROUP column */ check_val( ROW_VALUES(row)+1, DB1_STRING, 1, 1); str_vals[0] = (char*)VAL_STRING(ROW_VALUES(row)+1); /* PREFIX column - it may be null or empty */ check_val( ROW_VALUES(row)+2, DB1_STRING, 0, 0); if ((ROW_VALUES(row)+2)->nul || VAL_STRING(ROW_VALUES(row)+2)==0){ tmp.s = NULL; tmp.len = 0; } else { str_vals[1] = (char*)VAL_STRING(ROW_VALUES(row)+2); tmp.s = str_vals[1]; tmp.len = strlen(str_vals[1]); } /* TIME column */ check_val( ROW_VALUES(row)+3, DB1_STRING, 1, 1); str_vals[2] = (char*)VAL_STRING(ROW_VALUES(row)+3); /* PRIORITY column */ check_val( ROW_VALUES(row)+4, DB1_INT, 1, 0); int_vals[2] = VAL_INT (ROW_VALUES(row)+4); /* ROUTE_ID column */ check_val( ROW_VALUES(row)+5, DB1_STRING, 1, 0); str_vals[3] = (char*)VAL_STRING(ROW_VALUES(row)+5); /* DSTLIST column */ check_val( ROW_VALUES(row)+6, DB1_STRING, 1, 1); str_vals[4] = (char*)VAL_STRING(ROW_VALUES(row)+6); /* parse the time definition */ if ((time_rec=parse_time_def(str_vals[2]))==0) { LM_ERR("bad time definition <%s> for rule id %d -> skipping\n", str_vals[2], int_vals[0]); continue; } /* lookup for the script route ID */ if (str_vals[3][0] && str_vals[3][0]!='0') { int_vals[3] = route_lookup(&main_rt, str_vals[3]); if (int_vals[3]==-1) { LM_WARN("route <%s> does not exist\n",str_vals[3]); int_vals[3] = 0; } } else { int_vals[3] = 0; } /* is gw_list a list or a list id? */ if (str_vals[4][0]=='#') { s_id.s = str_vals[4]+1; s_id.len = strlen(s_id.s); if ( str2int( &s_id, &id)!=0 || (str_vals[4]=get_tmp_gw_list(id))==NULL ) { LM_ERR("invalid reference to a GW list <%s> -> skipping\n", str_vals[4]); continue; } } /* build the routing rule */ if ((ri = build_rt_info( int_vals[2], time_rec, int_vals[3], str_vals[4], rdata->pgw_l))== 0 ) { LM_ERR("failed to add routing info for rule id %d -> " "skipping\n", int_vals[0]); tmrec_free( time_rec ); continue; } /* add the rule */ if (add_rule( rdata, str_vals[0], &tmp, ri)!=0) { LM_ERR("failed to add rule id %d -> skipping\n", int_vals[0]); free_rt_info( ri ); continue; } n++; } if (DB_CAPABILITY(*dr_dbf, DB_CAP_FETCH)) { if(dr_dbf->fetch_result(db_hdl, &res, dr_fetch_rows)<0) { LM_ERR( "fetching rows (1)\n"); goto error; } } else { break; } } while(RES_ROW_N(res)>0); dr_dbf->free_result(db_hdl, res); res = 0; free_tmp_gw_list(); if (n==0) { LM_WARN("no valid routing rules -> discarding all destinations\n"); free_rt_data( rdata, 0 ); } return rdata; error: if (res) dr_dbf->free_result(db_hdl, res); if (rdata) free_rt_data( rdata, 1 ); rdata = NULL; return 0; }
/*---------------------------------------------------------------------------*/ uint8_t uip_over_mesh_send(void) { linkaddr_t receiver; struct route_entry *rt; /* This function is called by the uip-fw module to send out an IP packet. We try to send the IP packet to the next hop route, or we queue the packet and send out a route request for the final receiver of the packet. */ /* Packets destined to this network is sent using mesh, whereas packets destined to a network outside this network is sent towards the gateway node. */ if(uip_ipaddr_maskcmp(&BUF->destipaddr, &netaddr, &netmask)) { receiver.u8[0] = BUF->destipaddr.u8[2]; receiver.u8[1] = BUF->destipaddr.u8[3]; } else { if(linkaddr_cmp(&gateway, &linkaddr_node_addr)) { PRINTF("uip_over_mesh_send: I am gateway, packet to %d.%d.%d.%d to local interface\n", uip_ipaddr_to_quad(&BUF->destipaddr)); if(gw_netif != NULL) { return gw_netif->output(); } return UIP_FW_DROPPED; } else if(linkaddr_cmp(&gateway, &linkaddr_null)) { PRINTF("uip_over_mesh_send: No gateway setup, dropping packet\n"); return UIP_FW_OK; } else { PRINTF("uip_over_mesh_send: forwarding packet to %d.%d.%d.%d towards gateway %d.%d\n", uip_ipaddr_to_quad(&BUF->destipaddr), gateway.u8[0], gateway.u8[1]); linkaddr_copy(&receiver, &gateway); } } PRINTF("uIP over mesh send to %d.%d with len %d\n", receiver.u8[0], receiver.u8[1], uip_len); packetbuf_copyfrom(&uip_buf[UIP_LLH_LEN], uip_len); /* Send TCP data with the PACKETBUF_ATTR_ERELIABLE set so that an underlying power-saving MAC layer knows that it should be waiting for an ACK. */ if(BUF->proto == UIP_PROTO_TCP) { packetbuf_set_attr(PACKETBUF_ATTR_ERELIABLE, 1); packetbuf_set_attr(PACKETBUF_ATTR_RELIABLE, 1); /* packetbuf_set_attr(PACKETBUF_ATTR_PACKET_TYPE, PACKETBUF_ATTR_PACKET_TYPE_STREAM);*/ } rt = route_lookup(&receiver); if(rt == NULL) { PRINTF("uIP over mesh no route to %d.%d\n", receiver.u8[0], receiver.u8[1]); if(queued_packet == NULL) { queued_packet = queuebuf_new_from_packetbuf(); linkaddr_copy(&queued_receiver, &receiver); route_discovery_discover(&route_discovery, &receiver, ROUTE_TIMEOUT); } else if(!linkaddr_cmp(&queued_receiver, &receiver)) { route_discovery_discover(&route_discovery, &receiver, ROUTE_TIMEOUT); } } else { route_decay(rt); send_data(&rt->nexthop); } return UIP_FW_OK; }