opensips之fix_cmd_listeners()
来源:互联网 发布:易语言时时彩源码 编辑:程序博客网 时间:2024/06/06 16:27
枚举本服务器上的所有ip和本服务端口
fix_all_socket_lists();
/*return 0 on success, -1 on error */int fix_all_socket_lists(void){ int i; int found = 0; static char buf[5 /* currently sctp\0 is the largest protocol */]; char *p; for (i = PROTO_FIRST; i < PROTO_LAST; i++) { if (protos[i].id != PROTO_NONE) { if (fix_socket_list(&protos[i].listeners)!=0) { LM_ERR("fix_socket_list for %d failed\n", protos[i].id); goto error; } found++; } else if (protos[i].listeners) { p = proto2str(i, buf); if (p == NULL) goto error; *p = '\0'; LM_ERR("listeners found for protocol %s, but no module " "can handle it\n", buf); goto error; } } if (!found){ LM_ERR("no listening sockets\n"); goto error; } return 0;error: return -1;}
/* function will write the proto as string, starting from the p pointer. The new resulting proto will be returned (where writing ended) */static inline char* proto2str(int proto, char *p){ switch (proto) { case PROTO_UDP: *(p++) = 'u'; *(p++) = 'd'; *(p++) = 'p'; break; case PROTO_TCP: *(p++) = 't'; *(p++) = 'c'; *(p++) = 'p'; break; case PROTO_TLS: *(p++) = 't'; *(p++) = 'l'; *(p++) = 's'; break; case PROTO_SCTP: *(p++) = 's'; *(p++) = 'c'; *(p++) = 't'; *(p++) = 'p'; break; case PROTO_WS: *(p++) = 'w'; *(p++) = 's'; break; default: LM_CRIT("unsupported proto %d\n", proto); return 0; } return p;
/* fixes a socket list => resolve addresses, * interface names, fills missing members, remove duplicates */int fix_socket_list(struct socket_info **list){ struct socket_info* si; struct socket_info* l; struct socket_info* next; char* tmp; int len; struct hostent* he; char** h; /* try to change all the interface names into addresses * --ugly hack */ for (si=*list;si;){ next=si->next; if (add_interfaces(si->name.s, AF_INET, si->port_no, si->proto, list)!=-1){ /* success => remove current entry (shift the entire array)*/ sock_listrm(list, si); free_sock_info(si); } si=next; } /* get ips & fill the port numbers*/ for (si=*list;si;si=si->next){ /* fix the number of processes per interface */ if (!si->children && is_udp_based_proto(si->proto)) si->children = children_no; if (si->port_no==0) si->port_no= protos[si->proto].default_port; tmp=int2str(si->port_no, &len); if (len>=MAX_PORT_LEN){ LM_ERR("bad port number: %d\n", si->port_no); goto error; } si->port_no_str.s=(char*)pkg_malloc(len+1); if (si->port_no_str.s==0){ LM_ERR("out of pkg memory.\n"); goto error; } strncpy(si->port_no_str.s, tmp, len+1); si->port_no_str.len=len; /* get "official hostnames", all the aliases etc. */ he=resolvehost(si->name.s,0); if (he==0){ LM_ERR("could not resolve %s\n", si->name.s); goto error; } /* check if we got the official name */ if (strcasecmp(he->h_name, si->name.s)!=0){ if (auto_aliases && add_alias(si->name.s, si->name.len, si->port_no, si->proto)<0){ LM_ERR("add_alias failed\n"); } /* change the official name */ pkg_free(si->name.s); si->name.s=(char*)pkg_malloc(strlen(he->h_name)+1); if (si->name.s==0){ LM_ERR("out of pkg memory.\n"); goto error; } si->name.len=strlen(he->h_name); strncpy(si->name.s, he->h_name, si->name.len+1); } /* add the aliases*/ if (auto_aliases) { for(h=he->h_aliases; h && *h; h++) if (add_alias(*h, strlen(*h), si->port_no, si->proto)<0){ LM_ERR("add_alias failed\n"); } } hostent2ip_addr(&si->address, he, 0); /*convert to ip_addr format*/ if ((tmp=ip_addr2a(&si->address))==0) goto error; if (si->address.af == AF_INET6) { si->address_str.s=(char*)pkg_malloc(strlen(tmp)+1+2); if (si->address_str.s==0){ LM_ERR("out of pkg memory.\n"); goto error; } si->address_str.s[0] = '['; strncpy( si->address_str.s+1 , tmp, strlen(tmp)); si->address_str.s[1+strlen(tmp)] = ']'; si->address_str.s[2+strlen(tmp)] = '\0'; si->address_str.len=strlen(tmp) + 2; } else { si->address_str.s=(char*)pkg_malloc(strlen(tmp)+1); if (si->address_str.s==0){ LM_ERR("out of pkg memory.\n"); goto error; } strncpy(si->address_str.s, tmp, strlen(tmp)+1); si->address_str.len=strlen(tmp); } /* set is_ip (1 if name is an ip address, 0 otherwise) */ if ( auto_aliases && (si->address_str.len==si->name.len) && (strncasecmp(si->address_str.s, si->name.s, si->address_str.len)==0) ){ si->flags|=SI_IS_IP; /* do rev. DNS on it (for aliases)*/ he=rev_resolvehost(&si->address); if (he==0){ LM_WARN("could not rev. resolve %s\n", si->name.s); }else{ /* add the aliases*/ if (add_alias(he->h_name, strlen(he->h_name), si->port_no, si->proto)<0){ LM_ERR("add_alias failed\n"); } for(h=he->h_aliases; h && *h; h++) if (add_alias(*h,strlen(*h),si->port_no,si->proto)<0){ LM_ERR(" add_alias failed\n"); } } } /* Now build an ip_addr structure for the adv_name, if there is one * so that find_si can find it later easily. Doing this so that * we can force_send_socket() on an advertised name. Generally there * is little interest in dealing with an advertised name as anything * other than an opaque string that we blindly put into the SIP * message. */ if(si->adv_name_str.len) { /* If adv_name_str is already an IP, this is kinda foolish cus it * converts it to ip_addr, then to he, then here we go back to * ip_addr, but it's either that, or we duplicate the logic to * check for an ip address here, and still we might have to call * resolvehost(). */ he=resolvehost(si->adv_name_str.s,0); if (he==0){ LM_ERR("ERROR: fix_socket_list: could not resolve " "advertised name %s\n", si->adv_name_str.s); goto error; } hostent2ip_addr(&si->adv_address, he, 0); /*convert to ip_addr */ /* build and set string encoding for the adv socket info * This is usefful for the usrloc module when it's generating * or updating the socket on a location record, so we'll generate * it up front just like the regular sock_str so we don't have * to worry about it later. */ tmp = socket2str( si, 0, &si->adv_sock_str.len, 1); if (tmp==0) { LM_ERR("ERROR: fix_socket_list: failed to convert " "socket to string (adv)\n"); goto error; } si->adv_sock_str.s=(char*)pkg_malloc(si->adv_sock_str.len); if (si->adv_sock_str.s==0) { LM_ERR("ERROR: fix_socket_list: out of memory.\n"); goto error; } memcpy(si->adv_sock_str.s, tmp, si->adv_sock_str.len); } /* build and set string encoding for the real socket info */ tmp = socket2str( si, 0, &si->sock_str.len, 0); if (tmp==0) { LM_ERR("failed to convert socket to string"); goto error; } si->sock_str.s=(char*)pkg_malloc(si->sock_str.len); if (si->sock_str.s==0) { LM_ERR("out of pkg memory.\n"); goto error; } memcpy(si->sock_str.s, tmp, si->sock_str.len);#ifdef USE_MCAST /* Check if it is an multicast address and * set the flag if so */ if (is_mcast(&si->address)) { si->flags |= SI_IS_MCAST; }#endif /* USE_MCAST */#ifdef EXTRA_DEBUG printf(" %.*s [%s]:%s%s\n", si->name.len, si->name.s, si->address_str.s, si->port_no_str.s, si->flags & SI_IS_MCAST ? " mcast" : "");#endif } /* removing duplicate addresses*/ for (si=*list;si; si=si->next){ for (l=si->next;l;){ next=l->next; if ((si->port_no==l->port_no) && (si->address.af==l->address.af) && (memcmp(si->address.u.addr, l->address.u.addr, si->address.len) == 0) ){#ifdef EXTRA_DEBUG printf("removing duplicate %s [%s] == %s [%s]\n", si->name.s, si->address_str.s, l->name.s, l->address_str.s);#endif /* add the name to the alias list*/ if ((!(l->flags& SI_IS_IP)) && ( (l->name.len!=si->name.len)|| (strncmp(l->name.s, si->name.s, si->name.len)!=0)) ) add_alias(l->name.s, l->name.len, l->port_no, l->proto); /* remove l*/ sock_listrm(list, l); free_sock_info(l); } l=next; } }#ifdef USE_MCAST /* Remove invalid multicast entries */ si=*list; while(si){ if ((si->flags & SI_IS_MCAST) && (si->proto != PROTO_UDP) ){ LM_WARN("removing entry %s:%s [%s]:%s\n", get_proto_name(si->proto), si->name.s, si->address_str.s, si->port_no_str.s); l = si; si=si->next; sock_listrm(list, l); free_sock_info(l); } else { si=si->next; } }#endif /* USE_MCAST */ return 0;error: return -1;}
0 0
- opensips之fix_cmd_listeners()
- opensips之do_action()分析
- opensips之负载均衡
- opensips之opensipsdbctl
- opensips之yyparse( )
- (Opensips-wiki)Realtime OpenSIPS - FreeSWITCH Integration
- opensips学习(一)
- Opensips
- opensips
- opensips
- opensips添加自定义数据库表(mysql)
- opensips 开发日志1(配置独立的log文件)
- opensips.cfg研究分析(待完善修改)
- opensips配置
- OpenSIPS 研究
- opensips.cfg
- opensips tutorial
- OpenSIPS + RTPProxy
- libevent总结(上)
- 算法入门思维导图
- 学习之道
- MFC移植的问题
- Android5.x新特性之Toolbar,AppBarLayout,CoordinatorLayout,CollapsingToolbarLayout等汇总
- opensips之fix_cmd_listeners()
- Fragment.setArguments()的初衷。
- 【模板大法好】模拟退火算法
- c++学习感悟
- 【LeetCode-201】Bitwise AND of Numbers Range
- Fiddler AutoResponder Rule and Regular Expression
- 关于linux SCSI 子系统
- VC在Sql Server数据库中如何存取二进制图片信息
- 《精进,如何成为一个厉害的人》采桐