- sock_lists completely re-organized
[sip-router] / forward.c
index 82f9acb..4d3200c 100644 (file)
--- a/forward.c
+++ b/forward.c
@@ -43,6 +43,7 @@
  *               local replies (andrei)
  *  2003-08-21  check_self properly handles ipv6 addresses & refs   (andrei)
  *  2003-10-21  check_self updated to handle proto (andrei)
+ *  2003-10-24  converted to the new socket_info lists (andrei)
  */
 
 
@@ -71,6 +72,7 @@
 #include "ip_addr.h"
 #include "resolve.h"
 #include "name_alias.h"
+#include "socket_info.h"
 
 #ifdef DEBUG_DMALLOC
 #include <dmalloc.h>
@@ -87,15 +89,14 @@ struct socket_info* get_out_socket(union sockaddr_union* to, int proto)
 {
        int temp_sock;
        socklen_t len;
-       int r;
        union sockaddr_union from; 
+       struct socket_info* si;
 
        if (proto!=PROTO_UDP) {
                LOG(L_CRIT, "BUG: get_out_socket can only be called for UDP\n");
                return 0;
        }
-
-       r=-1;
+       
        temp_sock=socket(to->s.sa_family, SOCK_DGRAM, 0 );
        if (temp_sock==-1) {
                LOG(L_ERR, "ERROR: get_out_socket: socket() failed: %s\n",
@@ -113,38 +114,39 @@ struct socket_info* get_out_socket(union sockaddr_union* to, int proto)
                                strerror(errno));
                goto error;
        }
-       for (r=0; r<sock_no; r++) {
+       for (si=udp_listen; si; si=si->next) {
                switch(from.s.sa_family) {
                        case AF_INET:   
-                                               if (sock_info[r].address.af!=AF_INET)
+                                               if (si->address.af!=AF_INET)
                                                                continue;
-                                               if (memcmp(&sock_info[r].address.u,
+                                               if (memcmp(&si->address.u,
                                                                &from.sin.sin_addr, 
-                                                               sock_info[r].address.len)==0)
-                                                       goto error; /* it is actually success */
+                                                               si->address.len)==0)
+                                                       goto found; /*  success */
                                                break;
 #if defined(USE_IPV6)
                        case AF_INET6:  
-                                               if (sock_info[r].address.af!=AF_INET6)
+                                               if (si->address.af!=AF_INET6)
                                                                continue;
-                                               if (memcmp(&sock_info[r].address.u,
+                                               if (memcmp(&si->address.u,
                                                                &from.sin6.sin6_addr, len)==0)
-                                                       goto error;
+                                                       goto found;
                                                continue;
 #endif
                        default:        LOG(L_ERR, "ERROR: get_out_socket: "
                                                                        "unknown family: %d\n",
                                                                        from.s.sa_family);
-                                               r=-1;
                                                goto error;
                }
        }
-       LOG(L_ERR, "ERROR: get_out_socket: no socket found\n");
-       r=-1;
 error:
+       LOG(L_ERR, "ERROR: get_out_socket: no socket found\n");
+       close(temp_sock);
+       return 0;
+found:
        close(temp_sock);
-       DBG("DEBUG: get_out_socket: socket determined: %d\n", r );
-       return r==-1? 0: &sock_info[r];
+       DBG("DEBUG: get_out_socket: socket determined: %p\n", si );
+       return si;
 }
 
 
@@ -228,10 +230,10 @@ struct socket_info* get_send_socket(union sockaddr_union* to, int proto)
  */
 int check_self(str* host, unsigned short port, unsigned short proto)
 {
-       int r;
        char* hname;
        int h_len;
        struct socket_info* si;
+       unsigned short c_proto;
 #ifdef USE_IPV6
        struct ip_addr* ip6;
 #endif
@@ -245,76 +247,80 @@ int check_self(str* host, unsigned short port, unsigned short proto)
                h_len-=2;
        }
 #endif
-       /* get teh proper sock list */
-       switch(proto){
-               case PROTO_NONE: /* we'll use udp and not all the lists FIXME: */
-               case PROTO_UDP:
-                       si=sock_info;
-                       break;
+       c_proto=proto?proto:PROTO_UDP;
+       do{
+               /* get the proper sock list */
+               switch(c_proto){
+                       case PROTO_NONE: /* we'll use udp and not all the lists FIXME: */
+                       case PROTO_UDP:
+                               si=udp_listen;
+                               break;
 #ifdef USE_TCP
-               case PROTO_TCP:
-                       si=tcp_info;
-                       break;
+                       case PROTO_TCP:
+                               si=tcp_listen;
+                               break;
 #endif
 #ifdef USE_TLS
-               case PROTO_TLS:
-                       si=tls_info;
-                       break;
+                       case PROTO_TLS:
+                               si=tls_listen;
+                               break;
 #endif
-               default:
-                       /* unknown proto */
-                       LOG(L_WARN, "WARNING: check_self: unknown proto %d\n", proto);
-                       return 0; /* false */
-       }
-       for (r=0; r<sock_no; r++){
-               DBG("check_self - checking if host==us: %d==%d && "
-                               " [%.*s] == [%.*s]\n", 
-                                       h_len,
-                                       si[r].name.len,
-                                       h_len, hname,
-                                       si[r].name.len, si[r].name.s
-                       );
-               if (port) {
-                       DBG("check_self - checking if port %d matches port %d\n", 
-                                       si[r].port_no, port);
-                       if (si[r].port_no!=port) {
-                               continue;
-                       }
+                       default:
+                               /* unknown proto */
+                               LOG(L_WARN, "WARNING: check_self: "
+                                                       "unknown proto %d\n", c_proto);
+                               return 0; /* false */
                }
-               if ( (h_len==sock_info[r].name.len) && 
-                       (strncasecmp(hname, sock_info[r].name.s,
-                                    sock_info[r].name.len)==0) /*slower*/)
-                       /* comp. must be case insensitive, host names
-                        * can be written in mixed case, it will also match
-                        * ipv6 addresses if we are lucky*/
-                       break;
-       /* check if host == ip address */
+               for (; si; si=si->next){
+                       DBG("check_self - checking if host==us: %d==%d && "
+                                       " [%.*s] == [%.*s]\n", 
+                                               h_len,
+                                               si->name.len,
+                                               h_len, hname,
+                                               si->name.len, si->name.s
+                               );
+                       if (port) {
+                               DBG("check_self - checking if port %d matches port %d\n", 
+                                               si->port_no, port);
+                               if (si->port_no!=port) {
+                                       continue;
+                               }
+                       }
+                       if ( (h_len==si->name.len) && 
+                               (strncasecmp(hname, si->name.s,
+                                                si->name.len)==0) /*slower*/)
+                               /* comp. must be case insensitive, host names
+                                * can be written in mixed case, it will also match
+                                * ipv6 addresses if we are lucky*/
+                               goto found;
+               /* check if host == ip address */
 #ifdef USE_IPV6
-               /* ipv6 case is uglier, host can be [3ffe::1] */
-               ip6=str2ip6(host);
-               if (ip6){
-                       if (ip_addr_cmp(ip6, &sock_info[r].address))
-                               break; /* match */
-                       else
-                               continue; /* no match, but this is an ipv6 address
-                                                        so no point in trying ipv4 */
-               }
+                       /* ipv6 case is uglier, host can be [3ffe::1] */
+                       ip6=str2ip6(host);
+                       if (ip6){
+                               if (ip_addr_cmp(ip6, &si->address))
+                                       goto found; /* match */
+                               else
+                                       continue; /* no match, but this is an ipv6 address
+                                                                so no point in trying ipv4 */
+                       }
 #endif
-               /* ipv4 */
-               if (    (!sock_info[r].is_ip) &&
-                               (h_len==sock_info[r].address_str.len) && 
-                       (memcmp(hname, sock_info[r].address_str.s, 
-                                                               sock_info[r].address_str.len)==0)
-                       )
-                       break;
-       }
-       if (r==sock_no){
-               /* try to look into the aliases*/
-               if (grep_aliases(hname, h_len, port, proto)==0){
-                       DBG("check_self: host != me\n");
-                       return 0;
+                       /* ipv4 */
+                       if (    (!(si->flags&SI_IS_IP)) &&
+                                       (h_len==si->address_str.len) && 
+                               (memcmp(hname, si->address_str.s, 
+                                                                       si->address_str.len)==0)
+                               )
+                               goto found;
                }
+       }while( (proto==0) && (c_proto=next_proto(c_proto)) );
+       
+       /* try to look into the aliases*/
+       if (grep_aliases(hname, h_len, port, proto)==0){
+               DBG("check_self: host != me\n");
+               return 0;
        }
+found:
        return 1;
 }