core: option to set advertised address and port per socket
authorDaniel-Constantin Mierla <miconda@gmail.com>
Thu, 29 Mar 2012 10:27:19 +0000 (12:27 +0200)
committerDaniel-Constantin Mierla <miconda@gmail.com>
Thu, 29 Mar 2012 10:29:10 +0000 (12:29 +0200)
- listen parameter can be like:

listen=proto:ip:port advertise ip1:port1

- ip1 and port1 will be used to build Via and Route headers for messages
  using the socket

cfg.lex
cfg.y
ip_addr.h
main.c
msg_translator.c
socket_info.c
socket_info.h

diff --git a/cfg.lex b/cfg.lex
index 2d1494b..e2cbaf4 100644 (file)
--- a/cfg.lex
+++ b/cfg.lex
@@ -344,6 +344,7 @@ LOGSTDERROR log_stderror
 LOGFACILITY    log_facility
 LOGNAME                log_name
 LISTEN         listen
+ADVERTISE      advertise|ADVERTISE
 ALIAS          alias
 SR_AUTO_ALIASES        auto_aliases
 DNS             dns
@@ -714,6 +715,7 @@ IMPORTFILE      "import_file"
 <INITIAL>{LOGFACILITY} { yylval.strval=yytext; return LOGFACILITY; }
 <INITIAL>{LOGNAME}     { yylval.strval=yytext; return LOGNAME; }
 <INITIAL>{LISTEN}      { count(); yylval.strval=yytext; return LISTEN; }
+<INITIAL>{ADVERTISE}   { count(); yylval.strval=yytext; return ADVERTISE; }
 <INITIAL>{ALIAS}       { count(); yylval.strval=yytext; return ALIAS; }
 <INITIAL>{SR_AUTO_ALIASES}     { count(); yylval.strval=yytext;
                                                                        return SR_AUTO_ALIASES; }
diff --git a/cfg.y b/cfg.y
index 274e1e8..83a21df 100644 (file)
--- a/cfg.y
+++ b/cfg.y
@@ -400,6 +400,7 @@ extern char *finame;
 %token LOGFACILITY
 %token LOGNAME
 %token LISTEN
+%token ADVERTISE
 %token ALIAS
 %token SR_AUTO_ALIASES
 %token DNS
@@ -1540,6 +1541,20 @@ assign_stm:
                }
                free_socket_id_lst($3);
        }
+       | LISTEN EQUAL id_lst ADVERTISE listen_id COLON NUMBER {
+               for(lst_tmp=$3; lst_tmp; lst_tmp=lst_tmp->next) {
+                       if (add_listen_advertise_iface( lst_tmp->addr_lst->name,
+                                                                       lst_tmp->addr_lst->next,
+                                                                       lst_tmp->port, lst_tmp->proto,
+                                                                       $5, $7,
+                                                                       lst_tmp->flags)!=0) {
+                               LOG(L_CRIT,  "ERROR: cfg. parser: failed to add listen"
+                                                               " address\n");
+                               break;
+                       }
+               }
+               free_socket_id_lst($3);
+       }
        | LISTEN EQUAL  error { yyerror("ip address, interface name or"
                                                                        " hostname expected"); }
        | ALIAS EQUAL  id_lst {
index e162479..dbf6e85 100644 (file)
--- a/ip_addr.h
+++ b/ip_addr.h
@@ -102,6 +102,15 @@ struct addr_info{
        struct addr_info* prev;
 };
 
+struct advertise_info {
+       str name; /* name - eg.: foo.bar or 10.0.0.1 */
+       unsigned short port_no;  /* port number */
+       str port_no_str; /* port number converted to string -- optimization*/
+       str address_str;        /*ip address converted to string -- optimization*/
+       struct ip_addr address; /* ip address */
+       str sock_str; /* Socket proto, ip, and port as string */
+};
+
 struct socket_info{
        int socket;
        str name; /* name - eg.: foo.bar or 10.0.0.1 */
@@ -118,6 +127,7 @@ struct socket_info{
        struct addr_info* addr_info_lst; /* extra addresses (e.g. SCTP mh) */
        int workers; /* number of worker processes for this socket */
        int workers_tcpidx; /* index of workers in tcp children array */
+       struct advertise_info useinfo; /* details to be used in SIP msg */
 };
 
 
diff --git a/main.c b/main.c
index 75d972d..2774961 100644 (file)
--- a/main.c
+++ b/main.c
@@ -1596,13 +1596,25 @@ int main_loop()
                        nrprocs = (si->workers>0)?si->workers:children_no;
                        for(i=0;i<nrprocs;i++){
                                if(si->address.af==AF_INET6) {
-                                       snprintf(si_desc, MAX_PT_DESC, "udp receiver child=%d "
-                                               "sock=[%s]:%s",
-                                               i, si->name.s, si->port_no_str.s);
+                                       if(si->useinfo.name.s)
+                                               snprintf(si_desc, MAX_PT_DESC, "udp receiver child=%d "
+                                                       "sock=[%s]:%s (%s:%s)",
+                                                       i, si->name.s, si->port_no_str.s,
+                                                       si->useinfo.name.s, si->useinfo.port_no_str.s);
+                                       else
+                                               snprintf(si_desc, MAX_PT_DESC, "udp receiver child=%d "
+                                                       "sock=[%s]:%s",
+                                                       i, si->name.s, si->port_no_str.s);
                                } else {
-                                       snprintf(si_desc, MAX_PT_DESC, "udp receiver child=%d "
-                                               "sock=%s:%s",
-                                               i, si->name.s, si->port_no_str.s);
+                                       if(si->useinfo.name.s)
+                                               snprintf(si_desc, MAX_PT_DESC, "udp receiver child=%d "
+                                                       "sock=%s:%s (%s:%s)",
+                                                       i, si->name.s, si->port_no_str.s,
+                                                       si->useinfo.name.s, si->useinfo.port_no_str.s);
+                                       else
+                                               snprintf(si_desc, MAX_PT_DESC, "udp receiver child=%d "
+                                                       "sock=%s:%s",
+                                                       i, si->name.s, si->port_no_str.s);
                                }
                                child_rank++;
                                pid = fork_process(child_rank, si_desc, 1);
index 9b97794..1979f51 100644 (file)
@@ -579,6 +579,9 @@ static inline int lumps_len(struct sip_msg* msg, struct lump* lumps,
        struct lump* r;
        str* send_address_str;
        str* send_port_str;
+       str* recv_address_str;
+       str* recv_port_str;
+       int  recv_port_no;
        struct socket_info* send_sock;
        
 
@@ -623,7 +626,7 @@ static inline int lumps_len(struct sip_msg* msg, struct lump* lumps,
                switch((subst_l)->u.subst){ \
                        case SUBST_RCV_IP: \
                                if (msg->rcv.bind_address){ \
-                                       new_len+=msg->rcv.bind_address->address_str.len; \
+                                       new_len+=recv_address_str->len; \
                                        if (msg->rcv.bind_address->address.af!=AF_INET) \
                                                new_len+=2; \
                                }else{ \
@@ -633,7 +636,7 @@ static inline int lumps_len(struct sip_msg* msg, struct lump* lumps,
                                break; \
                        case SUBST_RCV_PORT: \
                                if (msg->rcv.bind_address){ \
-                                       new_len+=msg->rcv.bind_address->port_no_str.len; \
+                                       new_len+=recv_port_str->len; \
                                }else{ \
                                        /* FIXME */ \
                                        LOG(L_CRIT, "FIXME: null bind_address\n"); \
@@ -662,12 +665,12 @@ static inline int lumps_len(struct sip_msg* msg, struct lump* lumps,
                                break; \
                        case SUBST_RCV_ALL: \
                                if (msg->rcv.bind_address){ \
-                                       new_len+=msg->rcv.bind_address->address_str.len; \
+                                       new_len+=recv_address_str->len; \
                                        if (msg->rcv.bind_address->address.af!=AF_INET) \
                                                new_len+=2; \
-                                       if (msg->rcv.bind_address->port_no!=SIP_PORT){ \
+                                       if (recv_port_no!=SIP_PORT){ \
                                                /* add :port_no */ \
-                                               new_len+=1+msg->rcv.bind_address->port_no_str.len; \
+                                               new_len+=1+recv_port_str->len; \
                                        }\
                                                /*add;transport=xxx*/ \
                                        switch(msg->rcv.bind_address->proto){ \
@@ -780,15 +783,32 @@ static inline int lumps_len(struct sip_msg* msg, struct lump* lumps,
        s_offset=0;
        new_len=0;
        /* init send_address_str & send_port_str */
-       if (msg->set_global_address.len)
+       if(send_sock && send_sock->useinfo.name.len>0)
+               send_address_str=&(send_sock->useinfo.name);
+       else if (msg->set_global_address.len)
                send_address_str=&(msg->set_global_address);
        else
                send_address_str=&(send_sock->address_str);
-       if (msg->set_global_port.len)
+       if(send_sock && send_sock->useinfo.port_no>0)
+               send_port_str=&(send_sock->useinfo.port_no_str);
+       else if (msg->set_global_port.len)
                send_port_str=&(msg->set_global_port);
        else
                send_port_str=&(send_sock->port_no_str);
-
+       /* init recv_address_str, recv_port_str & recv_port_no */
+       if(msg->rcv.bind_address) {
+               if(msg->rcv.bind_address->useinfo.name.len>0)
+                       recv_address_str=&(msg->rcv.bind_address->useinfo.name);
+               else
+                       recv_address_str=&(msg->rcv.bind_address->address_str);
+               if(msg->rcv.bind_address->useinfo.port_no>0) {
+                       recv_port_str=&(msg->rcv.bind_address->useinfo.port_no_str);
+                       recv_port_no = msg->rcv.bind_address->useinfo.port_no;
+               } else {
+                       recv_port_str=&(msg->rcv.bind_address->port_no_str);
+                       recv_port_no = msg->rcv.bind_address->port_no;
+               }
+       }
 
        for(t=lumps;t;t=t->next){
                /* skip if this is an OPT lump and the condition is not satisfied */
@@ -898,6 +918,9 @@ static inline void process_lumps(   struct sip_msg* msg,
        int s_offset;
        str* send_address_str;
        str* send_port_str;
+       str* recv_address_str;
+       str* recv_port_str;
+       int  recv_port_no;
        struct socket_info* send_sock;
 
 #ifdef USE_COMP
@@ -958,9 +981,9 @@ static inline void process_lumps(   struct sip_msg* msg,
                                if (msg->rcv.bind_address->address.af!=AF_INET){\
                                        new_buf[offset]='['; offset++; \
                                }\
-                               memcpy(new_buf+offset, msg->rcv.bind_address->address_str.s, \
-                                               msg->rcv.bind_address->address_str.len); \
-                               offset+=msg->rcv.bind_address->address_str.len; \
+                               memcpy(new_buf+offset, recv_address_str->s, \
+                                               recv_address_str->len); \
+                               offset+=recv_address_str->len; \
                                if (msg->rcv.bind_address->address.af!=AF_INET){\
                                        new_buf[offset]=']'; offset++; \
                                }\
@@ -971,9 +994,9 @@ static inline void process_lumps(   struct sip_msg* msg,
                        break; \
                case SUBST_RCV_PORT: \
                        if (msg->rcv.bind_address){  \
-                               memcpy(new_buf+offset, msg->rcv.bind_address->port_no_str.s, \
-                                               msg->rcv.bind_address->port_no_str.len); \
-                               offset+=msg->rcv.bind_address->port_no_str.len; \
+                               memcpy(new_buf+offset, recv_port_str->s, \
+                                               recv_port_str->len); \
+                               offset+=recv_port_str->len; \
                        }else{  \
                                /*FIXME*/ \
                                LOG(L_CRIT, "FIXME: process_lumps: null bind_address\n"); \
@@ -985,19 +1008,19 @@ static inline void process_lumps(        struct sip_msg* msg,
                                if (msg->rcv.bind_address->address.af!=AF_INET){\
                                        new_buf[offset]='['; offset++; \
                                }\
-                               memcpy(new_buf+offset, msg->rcv.bind_address->address_str.s, \
-                                               msg->rcv.bind_address->address_str.len); \
-                               offset+=msg->rcv.bind_address->address_str.len; \
+                               memcpy(new_buf+offset, recv_address_str->s, \
+                                               recv_address_str->len); \
+                               offset+=recv_address_str->len; \
                                if (msg->rcv.bind_address->address.af!=AF_INET){\
                                        new_buf[offset]=']'; offset++; \
                                }\
                                /* :port */ \
-                               if (msg->rcv.bind_address->port_no!=SIP_PORT){ \
+                               if (recv_port_no!=SIP_PORT){ \
                                        new_buf[offset]=':'; offset++; \
                                        memcpy(new_buf+offset, \
-                                                       msg->rcv.bind_address->port_no_str.s, \
-                                                       msg->rcv.bind_address->port_no_str.len); \
-                                       offset+=msg->rcv.bind_address->port_no_str.len; \
+                                                       recv_port_str->s, \
+                                                       recv_port_str->len); \
+                                       offset+=recv_port_str->len; \
                                }\
                                switch(msg->rcv.bind_address->proto){ \
                                        case PROTO_NONE: \
@@ -1200,7 +1223,33 @@ static inline void process_lumps(        struct sip_msg* msg,
                send_port_str=&(msg->set_global_port);
        else
                send_port_str=&(send_sock->port_no_str);
-
+       /* init send_address_str & send_port_str */
+       if(send_sock && send_sock->useinfo.name.len>0)
+               send_address_str=&(send_sock->useinfo.name);
+       else if (msg->set_global_address.len)
+               send_address_str=&(msg->set_global_address);
+       else
+               send_address_str=&(send_sock->address_str);
+       if(send_sock && send_sock->useinfo.port_no>0)
+               send_port_str=&(send_sock->useinfo.port_no_str);
+       else if (msg->set_global_port.len)
+               send_port_str=&(msg->set_global_port);
+       else
+               send_port_str=&(send_sock->port_no_str);
+       /* init recv_address_str, recv_port_str & recv_port_no */
+       if(msg->rcv.bind_address) {
+               if(msg->rcv.bind_address->useinfo.name.len>0)
+                       recv_address_str=&(msg->rcv.bind_address->useinfo.name);
+               else
+                       recv_address_str=&(msg->rcv.bind_address->address_str);
+               if(msg->rcv.bind_address->useinfo.port_no>0) {
+                       recv_port_str=&(msg->rcv.bind_address->useinfo.port_no_str);
+                       recv_port_no = msg->rcv.bind_address->useinfo.port_no;
+               } else {
+                       recv_port_str=&(msg->rcv.bind_address->port_no_str);
+                       recv_port_no = msg->rcv.bind_address->port_no;
+               }
+       }
 
        orig=msg->buf;
        offset=*new_buf_offs;
@@ -2276,13 +2325,17 @@ char* via_builder( unsigned int *len,
 #endif /* USE_COMP */
 
        send_sock=send_info->send_sock;
-       /* use pre-set address in via or the outbound socket one */
-       if ( hp && hp->host->len)
+       /* use pre-set address in via, the outbound socket alias or address one */
+       if (hp && hp->host->len)
                address_str=hp->host;
+       else if(send_sock->useinfo.name.len>0)
+               address_str=&(send_sock->useinfo.name);
        else
                address_str=&(send_sock->address_str);
        if (hp && hp->port->len)
                port_str=hp->port;
+       else if(send_sock->useinfo.port_no>0)
+               port_str=&(send_sock->useinfo.port_no_str);
        else
                port_str=&(send_sock->port_no_str);
        
index 4bec67e..d439bce 100644 (file)
@@ -235,10 +235,13 @@ error:
 static inline struct socket_info* new_sock_info(       char* name,
                                                                struct name_lst* addr_l,
                                                                unsigned short port, unsigned short proto,
+                                                               char *usename, unsigned short useport,
                                                                enum si_flags flags)
 {
        struct socket_info* si;
        struct name_lst* n;
+       struct hostent* he;
+       char *p;
        
        si=(struct socket_info*) pkg_malloc(sizeof(struct socket_info));
        if (si==0) goto error;
@@ -259,10 +262,51 @@ static inline struct socket_info* new_sock_info(  char* name,
                        goto error;
                }
        }
+       if(usename!=NULL)
+       {
+               si->useinfo.name.len=strlen(usename);
+               si->useinfo.name.s=(char*)pkg_malloc(si->useinfo.name.len+1);
+               if (si->useinfo.name.s==0)
+                       goto error;
+               strcpy(si->useinfo.name.s, usename);
+               if(usename[0]=='[' && usename[si->useinfo.name.len-1]==']')
+               {
+                       si->useinfo.address_str.len = si->useinfo.name.len - 2;
+                       p = si->useinfo.name.s + 1;
+               } else {
+                       si->useinfo.address_str.len = si->useinfo.name.len;
+                       p = si->useinfo.name.s;
+               }
+               si->useinfo.address_str.s=(char*)pkg_malloc(si->useinfo.address_str.len+1);
+               if(si->useinfo.address_str.s==NULL)
+                       goto error;
+               strncpy(si->useinfo.address_str.s, p, si->useinfo.address_str.len);
+               si->useinfo.address_str.s[si->useinfo.address_str.len] = '\0';
+
+               p = int2str(useport, &si->useinfo.port_no_str.len);
+               if(p==NULL)
+                       goto error;
+               si->useinfo.port_no_str.s=(char*)pkg_malloc(si->useinfo.port_no_str.len+1);
+               if(si->useinfo.port_no_str.s==NULL)
+                       goto error;
+               strcpy(si->useinfo.port_no_str.s, p);
+               si->useinfo.port_no = useport;
+
+               he=resolvehost(si->useinfo.name.s);
+               if (he==0){
+                       LM_ERR(" unable to resolve advertised name %s\n", si->useinfo.name.s);
+                       goto error;
+               }
+               hostent2ip_addr(&si->useinfo.address, he, 0);
+       }
        return si;
 error:
        LOG(L_ERR, "ERROR: new_sock_info: memory allocation error\n");
-       if (si) pkg_free(si);
+       if (si) {
+               if(si->name.s)
+                       pkg_free(si->name.s);
+               pkg_free(si);
+       }
        return 0;
 }
 
@@ -275,8 +319,11 @@ static void free_sock_info(struct socket_info* si)
                if(si->name.s) pkg_free(si->name.s);
                if(si->address_str.s) pkg_free(si->address_str.s);
                if(si->port_no_str.s) pkg_free(si->port_no_str.s);
-               if (si->addr_info_lst) free_addr_info_lst(&si->addr_info_lst);
+               if(si->addr_info_lst) free_addr_info_lst(&si->addr_info_lst);
                if(si->sock_str.s) pkg_free(si->sock_str.s);
+               if(si->useinfo.name.s) pkg_free(si->useinfo.name.s);
+               if(si->useinfo.port_no_str.s) pkg_free(si->useinfo.port_no_str.s);
+               if(si->useinfo.sock_str.s) pkg_free(si->useinfo.sock_str.s);
        }
 }
 
@@ -321,6 +368,11 @@ static char* get_valid_proto_name(unsigned short proto)
  * @return -1 on error and 0 on success
  */
 int socket2str(char* s, int* len, struct socket_info* si)
+{
+       return socketinfo2str(s, len, si, 0);
+}
+
+int socketinfo2str(char* s, int* len, struct socket_info* si, int mode)
 {
        str proto;
        int l;
@@ -328,13 +380,16 @@ int socket2str(char* s, int* len, struct socket_info* si)
        proto.s = get_valid_proto_name(si->proto);
        proto.len = strlen(proto.s);
        
-       l = proto.len + si->address_str.len + si->port_no_str.len + 2;
+       if(mode==1)
+               l = proto.len + si->useinfo.name.len + si->useinfo.port_no_str.len + 2;
+       else
+               l = proto.len + si->address_str.len + si->port_no_str.len + 2;
 
        if(si->address.af==AF_INET6)
                l += 2;
        
        if (*len < l) {
-               ERR("socket2str: Destionation buffer too short\n");
+               LM_ERR("Destionation buffer too short\n");
                *len = l;
                return -1;
        }
@@ -342,17 +397,25 @@ int socket2str(char* s, int* len, struct socket_info* si)
        memcpy(s, proto.s, proto.len);
        s += proto.len;
        *s = ':'; s++;
-       if(si->address.af==AF_INET6) {
-               *s = '['; s++;
-       }
-       memcpy(s, si->address_str.s, si->address_str.len);
-       s += si->address_str.len;
-       if(si->address.af==AF_INET6) {
-               *s = ']'; s++;
+       if(mode==1){
+               memcpy(s, si->useinfo.name.s, si->useinfo.name.len);
+               s += si->useinfo.name.len;
+               *s = ':'; s++;
+               memcpy(s, si->useinfo.port_no_str.s, si->useinfo.port_no_str.len);
+               s += si->useinfo.port_no_str.len;
+       } else {
+               if(si->address.af==AF_INET6) {
+                       *s = '['; s++;
+               }
+               memcpy(s, si->address_str.s, si->address_str.len);
+               s += si->address_str.len;
+               if(si->address.af==AF_INET6) {
+                       *s = ']'; s++;
+               }
+               *s = ':'; s++;
+               memcpy(s, si->port_no_str.s, si->port_no_str.len);
+               s += si->port_no_str.len;
        }
-       *s = ':'; s++;
-       memcpy(s, si->port_no_str.s, si->port_no_str.len);
-       s += si->port_no_str.len;
 
        *len = l;
        return 0;
@@ -375,12 +438,30 @@ static int fix_sock_str(struct socket_info* si)
                ERR("fix_sock_str: No memory left\n");
                return -1;
        }
-       if (socket2str(si->sock_str.s, &len, si) < 0) {
-               BUG("fix_sock_str: Error in socket2str\n");
+       if (socketinfo2str(si->sock_str.s, &len, si, 0) < 0) {
+               BUG("fix_sock_str: Error in socket to str\n");
                return -1;
        }
        si->sock_str.s[len] = '\0';
        si->sock_str.len = len;
+       if(si->useinfo.name.s!=NULL)
+       {
+               len = MAX_SOCKET_STR;
+
+               if (si->useinfo.sock_str.s) pkg_free(si->useinfo.sock_str.s);
+
+               si->useinfo.sock_str.s = pkg_malloc(len + 1);
+               if (si->useinfo.sock_str.s == NULL) {
+                       ERR("fix_sock_str: No memory left\n");
+                       return -1;
+               }
+               if (socketinfo2str(si->useinfo.sock_str.s, &len, si, 1) < 0) {
+                       BUG("fix_sock_str: Error in socket to str\n");
+                       return -1;
+               }
+               si->useinfo.sock_str.s[len] = '\0';
+               si->useinfo.sock_str.len = len;
+       }
        return 0;
 }
 
@@ -493,23 +574,38 @@ struct socket_info* grep_sock_info(str* host, unsigned short port,
                if (list==0) /* disabled or unknown protocol */
                        continue;
                for (si=*list; si; si=si->next){
-                       DBG("grep_sock_info - checking if host==us: %d==%d && "
-                                       " [%.*s] == [%.*s]\n", 
+                       DBG("grep_sock_info - checking if host==us: %d==%d &&"
+                                       " [%.*s] == [%.*s]\n",
                                                hname.len,
                                                si->name.len,
                                                hname.len, hname.s,
                                                si->name.len, si->name.s
                                );
                        if (port) {
-                               DBG("grep_sock_info - checking if port %d matches port %d\n", 
-                                               si->port_no, port);
-                               if (si->port_no!=port) {
+                               DBG("grep_sock_info - checking if port %d (advertise %d)"
+                                               " matches port %d\n",
+                                               si->port_no, si->useinfo.port_no, port);
+                               if (si->port_no!=port && si->useinfo.port_no!=port) {
                                        continue;
                                }
                        }
                        if (si_hname_cmp(&hname, &si->name, &si->address_str, 
                                                                &si->address, si->flags)==0)
                                goto found;
+                       if(si->useinfo.name.s!=NULL)
+                       {
+                               DBG("grep_sock_info - checking advertise if host==us:"
+                                               " %d==%d && [%.*s] == [%.*s]\n",
+                                               hname.len,
+                                               si->useinfo.name.len,
+                                               hname.len, hname.s,
+                                               si->useinfo.name.len, si->useinfo.name.s
+                               );
+                               if (si_hname_cmp(&hname, &si->useinfo.name,
+                                                       &si->useinfo.address_str, &si->useinfo.address,
+                                                       si->flags)==0)
+                                       goto found;
+                       }
                        /* try among the extra addresses */
                        for (ai=si->addr_info_lst; ai; ai=ai->next)
                                if (si_hname_cmp(&hname, &ai->name, &ai->address_str, 
@@ -593,7 +689,8 @@ struct socket_info* find_si(struct ip_addr* ip, unsigned short port,
                                        continue;
                                }
                        }
-                       if (ip_addr_cmp(ip, &si->address))
+                       if (ip_addr_cmp(ip, &si->address)
+                                       || ip_addr_cmp(ip, &si->useinfo.address))
                                goto found;
                        for (ai=si->addr_info_lst; ai; ai=ai->next)
                                if (ip_addr_cmp(ip, &ai->address))
@@ -612,12 +709,14 @@ found:
  * return  new sock info on success, 0 on error */
 static struct socket_info* new_sock2list(char* name, struct name_lst* addr_l,
                                                                        unsigned short port,
-                                                                       unsigned short proto, enum si_flags flags,
+                                                                       unsigned short proto,
+                                                                       char *usename, unsigned short useport,
+                                                                       enum si_flags flags,
                                                                        struct socket_info** list)
 {
        struct socket_info* si;
        
-       si=new_sock_info(name, addr_l, port, proto, flags);
+       si=new_sock_info(name, addr_l, port, proto, usename, useport, flags);
        if (si==0){
                LOG(L_ERR, "ERROR: new_sock2list: new_sock_info failed\n");
                goto error;
@@ -639,12 +738,15 @@ error:
 static struct socket_info* new_sock2list_after(char* name,
                                                                        struct name_lst* addr_l,
                                                                        unsigned short port,
-                                                                       unsigned short proto, enum si_flags flags,
+                                                                       unsigned short proto,
+                                                                       char *usename,
+                                                                       unsigned short useport,
+                                                                       enum si_flags flags,
                                                                        struct socket_info* after)
 {
        struct socket_info* si;
        
-       si=new_sock_info(name, addr_l, port, proto, flags);
+       si=new_sock_info(name, addr_l, port, proto, usename, useport, flags);
        if (si==0){
                LOG(L_ERR, "ERROR: new_sock2list_after: new_sock_info failed\n");
                goto error;
@@ -659,8 +761,9 @@ error:
 
 /* adds a sock_info structure to the corresponding proto list
  * return  0 on success, -1 on error */
-int add_listen_iface(char* name, struct name_lst* addr_l,
+int add_listen_advertise_iface(char* name, struct name_lst* addr_l,
                                                unsigned short port, unsigned short proto,
+                                               char *usename, unsigned short useport,
                                                enum si_flags flags)
 {
        struct socket_info** list;
@@ -691,7 +794,7 @@ int add_listen_iface(char* name, struct name_lst* addr_l,
                        c_port=port;
                }
                if (c_proto!=PROTO_SCTP){
-                       if (new_sock2list(name, 0, c_port, c_proto,
+                       if (new_sock2list(name, 0, c_port, c_proto, usename, useport,
                                                                flags & ~SI_IS_MHOMED, list)==0){
                                LOG(L_ERR, "ERROR: add_listen_iface: new_sock2list failed\n");
                                goto error;
@@ -700,14 +803,16 @@ int add_listen_iface(char* name, struct name_lst* addr_l,
                         * since only SCTP can bind to multiple addresses */
                        for (a_l=addr_l; a_l; a_l=a_l->next){
                                if (new_sock2list(a_l->name, 0, c_port, 
-                                                                       c_proto, flags & ~SI_IS_MHOMED, list)==0){
+                                                                       c_proto, usename, useport,
+                                                                       flags & ~SI_IS_MHOMED, list)==0){
                                        LOG(L_ERR, "ERROR: add_listen_iface: new_sock2list"
                                                                " failed\n");
                                        goto error;
                                }
                        }
                }else{
-                       if (new_sock2list(name, addr_l, c_port, c_proto, flags, list)==0){
+                       if (new_sock2list(name, addr_l, c_port, c_proto, usename, useport,
+                                               flags, list)==0){
                                LOG(L_ERR, "ERROR: add_listen_iface: new_sock2list failed\n");
                                goto error;
                        }
@@ -718,6 +823,14 @@ error:
        return -1;
 }
 
+/* adds a sock_info structure to the corresponding proto list
+ * return  0 on success, -1 on error */
+int add_listen_iface(char* name, struct name_lst* addr_l,
+                                               unsigned short port, unsigned short proto,
+                                               enum si_flags flags)
+{
+       return add_listen_advertise_iface(name, addr_l, port, proto, 0, 0, flags);
+}
 #ifdef __OS_linux
 
 #include "linux/netlink.h"
@@ -1323,8 +1436,8 @@ static int addr_info_to_si_lst(struct addr_info* ai_lst, unsigned short port,
        struct addr_info* ail;
        
        for (ail=ai_lst; ail; ail=ail->next){
-               if(new_sock2list(ail->name.s, 0, port, proto, ail->flags | flags,
-                                                       list)==0)
+               if(new_sock2list(ail->name.s, 0, port, proto, 0, 0,
+                                       ail->flags | flags, list)==0)
                        return -1;
        }
        return 0;
@@ -1346,7 +1459,7 @@ static int addr_info_to_si_lst_after(struct addr_info* ai_lst,
        
        for (ail=ai_lst; ail; ail=ail->next){
                if((new_si=new_sock2list_after(ail->name.s, 0, port, proto,
-                                                               ail->flags | flags, el))==0)
+                                                               0, 0, ail->flags | flags, el))==0)
                        return -1;
                el=new_si;
        }
@@ -1386,7 +1499,8 @@ static int fix_socket_list(struct socket_info **list, int* type_flags)
                                                        si->proto, &ai_lst)!=-1){
                        if (si->flags & SI_IS_MHOMED){
                                if((new_si=new_sock2list_after(ai_lst->name.s, 0, si->port_no,
-                                                                                       si->proto,
+                                                                                       si->proto, si->useinfo.name.s,
+                                                                                       si->useinfo.port_no,
                                                                                        ai_lst->flags|si->flags, si))==0)
                                        break;
                                ail=ai_lst;
index 7923e65..99accd8 100644 (file)
@@ -50,6 +50,7 @@
        INT2STR_MAX_LEN + 2 + 2)
 
 int socket2str(char* s, int* len, struct socket_info* si);
+int socketinfo2str(char* s, int* len, struct socket_info* si, int mode);
 
 
 /* struct socket_info is defined in ip_addr.h */
@@ -84,6 +85,10 @@ void init_proto_order();
 int add_listen_iface(char* name, struct name_lst* nlst,
                                                unsigned short port, unsigned short proto,
                                                enum si_flags flags);
+int add_listen_advertise_iface(char* name, struct name_lst* nlst,
+                                               unsigned short port, unsigned short proto,
+                                               char *useaddr, unsigned short useport,
+                                               enum si_flags flags);
 int fix_all_socket_lists();
 void print_all_socket_lists();
 void print_aliases();