Navigation


Changeset 210:2b5027949f85 in freeDiameter for freeDiameter/endpoints.c


Ignore:
Timestamp:
Feb 16, 2010, 4:33:03 PM (14 years ago)
Author:
Sebastien Decugis <sdecugis@nict.go.jp>
Branch:
default
Phase:
public
Message:

Fix issue where the same address can be added several times in a list

File:
1 edited

Legend:

Unmodified
Added
Removed
  • freeDiameter/endpoints.c

    r178 r210  
    4747                sSA6 *sin6;
    4848        } ptr;
     49        in_port_t * port;
    4950        int cmp = -1;
    5051       
     
    5253        CHECK_PARAMS( list && sa && (sl <= sizeof(sSS)) );
    5354       
     55        ptr.sa = sa;
     56       
    5457        /* Filter out a bunch of invalid addresses */
    55         if (! (flags & EP_ACCEPTALL)) {
    56                 ptr.sa = sa;
    57                 switch (sa->sa_family) {
    58                         case AF_INET:
     58        switch (sa->sa_family) {
     59                case AF_INET:
     60                        if (! (flags & EP_ACCEPTALL)) {
    5961                                if (IN_IS_ADDR_UNSPECIFIED(&ptr.sin->sin_addr)
    6062                                 || IN_IS_ADDR_LOOPBACK(&ptr.sin->sin_addr)
     
    6466                                 || (ptr.sin->sin_addr.s_addr == INADDR_BROADCAST))
    6567                                        return 0;
    66                                 break;
    67 
    68                         case AF_INET6:
     68                        }
     69                        port = &ptr.sin->sin_port;
     70                        break;
     71
     72                case AF_INET6:
     73                        if (! (flags & EP_ACCEPTALL)) {
    6974                                if (IN6_IS_ADDR_UNSPECIFIED(&ptr.sin6->sin6_addr)
    7075                                 || IN6_IS_ADDR_LOOPBACK(&ptr.sin6->sin6_addr)
     
    7378                                 || IN6_IS_ADDR_SITELOCAL(&ptr.sin6->sin6_addr))
    7479                                        return 0;
     80                        }
     81                        port = &ptr.sin6->sin6_port;
     82                        break;
     83
     84                default:
     85                        return 0;
     86        }
     87
     88        /* remove the ACCEPTALL flag */
     89        flags &= ~EP_ACCEPTALL;
     90       
     91        /* Search place in the list */
     92        for (li = list->next; li != list; li = li->next) {
     93                ep = (struct fd_endpoint *)li;
     94                in_port_t * ep_port;
     95               
     96                /* First, compare the address family */
     97                if (ep->sa.sa_family < sa->sa_family)
     98                        continue;
     99                if (ep->sa.sa_family > sa->sa_family)
     100                        break;
     101               
     102                /* Then compare the address field */
     103                switch (sa->sa_family) {
     104                        case AF_INET:
     105                                cmp = memcmp(&ep->sin.sin_addr, &ptr.sin->sin_addr, sizeof(struct in_addr));
     106                                ep_port = &ep->sin.sin_port;
    75107                                break;
    76 
     108                        case AF_INET6:
     109                                cmp = memcmp(&ep->sin6.sin6_addr, &ptr.sin6->sin6_addr, sizeof(struct in6_addr));
     110                                ep_port = &ep->sin6.sin6_port;
     111                                break;
    77112                        default:
     113                                /* Filter this out */
    78114                                return 0;
    79115                }
    80         } else {
    81                 /* remove it */
    82                 flags &= ~EP_ACCEPTALL;
    83         }
    84        
    85         /* Search place in the list */
    86         for (li = list->next; li != list; li = li->next) {
    87                 ep = (struct fd_endpoint *)li;
    88                
    89                 cmp = memcmp(&ep->ss, sa, sl);
    90                 if (cmp >= 0)
    91                         break;
     116                if (cmp < 0)
     117                        continue;
     118                if (cmp > 0)
     119                        break;
     120               
     121                /* Finally compare the port, only if not 0 */
     122                if (*port == 0)
     123                        break;
     124                if (*ep_port == 0) {
     125                        /* save the port information in the list, and break */
     126                        *ep_port = *port;
     127                        break;
     128                }
     129                if (*ep_port < *port)
     130                        continue;
     131                if (*ep_port > *port)
     132                        cmp = 1;
     133                break;
    92134        }
    93135       
Note: See TracChangeset for help on using the changeset viewer.