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