Navigation


Changeset 378:41e3c2a3721c in freeDiameter


Ignore:
Timestamp:
Jul 5, 2010, 4:21:22 PM (14 years ago)
Author:
Sebastien Decugis <sdecugis@nict.go.jp>
Branch:
default
Phase:
public
Message:

Replaced old mechanism to discover local addresses by a call to getifaddrs, lot cleaner!
Should close #4

Files:
9 edited

Legend:

Unmodified
Added
Removed
  • freeDiameter/cnxctx.c

    r258 r378  
    3737#include "cnxctx.h"
    3838
     39#include <net/if.h>
     40#include <ifaddrs.h> /* for getifaddrs */
     41
    3942/* The maximum size of Diameter message we accept to receive (<= 2^24) to avoid too big mallocs in case of trashed headers */
    4043#ifndef DIAMETER_MSG_SIZE_MAX
    4144#define DIAMETER_MSG_SIZE_MAX   65535   /* in bytes */
    4245#endif /* DIAMETER_MSG_SIZE_MAX */
     46
    4347
    4448/* Connections contexts (cnxctx) in freeDiameter are wrappers around the sockets and TLS operations .
     
    7478 */
    7579
    76 
    7780/*******************************************/
    7881/*     Creation of a connection object     */
     
    468471
    469472/* Get the list of endpoints (IP addresses) of the local and remote peers on this connection */
    470 int fd_cnx_getendpoints(struct cnxctx * conn, struct fd_list * local, struct fd_list * remote)
    471 {
    472         TRACE_ENTRY("%p %p %p", conn, local, remote);
    473         CHECK_PARAMS(conn);
    474        
    475         if (local) {
    476                 /* Retrieve the local endpoint(s) of the connection */
    477                 switch (conn->cc_proto) {
    478                         case IPPROTO_TCP: {
    479                                 sSS ss;
    480                                 socklen_t sl;
    481                                 CHECK_FCT(fd_tcp_get_local_ep(conn->cc_socket, &ss, &sl));
    482                                 CHECK_FCT(fd_ep_add_merge( local, (sSA *)&ss, sl, EP_FL_LL | EP_FL_PRIMARY));
    483                         }
    484                         break;
    485 
    486                         #ifndef DISABLE_SCTP
    487                         case IPPROTO_SCTP: {
    488                                 CHECK_FCT(fd_sctp_get_local_ep(conn->cc_socket, local));
    489                         }
    490                         break;
    491                         #endif /* DISABLE_SCTP */
    492 
    493                         default:
    494                                 CHECK_PARAMS(0);
    495                 }
    496         }
    497        
    498         if (remote) {
    499                 /* Check we have a full connection object, not a listening socket (with no remote) */
    500                 CHECK_PARAMS( conn->cc_incoming );
    501                
    502                 /* Retrieve the peer endpoint(s) of the connection */
    503                 switch (conn->cc_proto) {
    504                         case IPPROTO_TCP: {
    505                                 sSS ss;
    506                                 socklen_t sl;
    507                                 CHECK_FCT(fd_tcp_get_remote_ep(conn->cc_socket, &ss, &sl));
    508                                 CHECK_FCT(fd_ep_add_merge( remote, (sSA *)&ss, sl, EP_FL_LL | EP_FL_PRIMARY ));
    509                         }
    510                         break;
    511 
    512                         #ifndef DISABLE_SCTP
    513                         case IPPROTO_SCTP: {
    514                                 CHECK_FCT(fd_sctp_get_remote_ep(conn->cc_socket, remote));
    515                         }
    516                         break;
    517                         #endif /* DISABLE_SCTP */
    518 
    519                         default:
    520                                 CHECK_PARAMS(0);
    521                 }
     473int fd_cnx_getremoteeps(struct cnxctx * conn, struct fd_list * eps)
     474{
     475        TRACE_ENTRY("%p %p %p", conn, eps);
     476        CHECK_PARAMS(conn && eps);
     477       
     478        /* Check we have a full connection object, not a listening socket (with no remote) */
     479        CHECK_PARAMS( conn->cc_incoming );
     480
     481        /* Retrieve the peer endpoint(s) of the connection */
     482        switch (conn->cc_proto) {
     483                case IPPROTO_TCP: {
     484                        sSS ss;
     485                        socklen_t sl;
     486                        CHECK_FCT(fd_tcp_get_remote_ep(conn->cc_socket, &ss, &sl));
     487                        CHECK_FCT(fd_ep_add_merge( eps, (sSA *)&ss, sl, EP_FL_LL | EP_FL_PRIMARY ));
     488                }
     489                break;
     490
     491                #ifndef DISABLE_SCTP
     492                case IPPROTO_SCTP: {
     493                        CHECK_FCT(fd_sctp_get_remote_ep(conn->cc_socket, eps));
     494                }
     495                break;
     496                #endif /* DISABLE_SCTP */
     497
     498                default:
     499                        CHECK_PARAMS(0);
    522500        }
    523501
    524502        return 0;
    525503}
    526 
    527504
    528505/* Get a string describing the remote peer address (ip address or fqdn) */
     
    531508        CHECK_PARAMS_DO( conn, return "" );
    532509        return conn->cc_remid;
     510}
     511
     512/* Retrieve a list of all IP addresses of the local system from the kernel, using  */
     513int fd_cnx_get_local_eps(struct fd_list * list)
     514{
     515        struct ifaddrs *iflist, *cur;
     516        CHECK_SYS(getifaddrs(&iflist));
     517       
     518        for (cur = iflist; cur != NULL; cur = cur->ifa_next) {
     519                if (cur->ifa_flags & IFF_LOOPBACK)
     520                        continue;
     521               
     522                if (fd_g_config->cnf_flags.no_ip4 && (cur->ifa_addr->sa_family == AF_INET))
     523                        continue;
     524               
     525                if (fd_g_config->cnf_flags.no_ip6 && (cur->ifa_addr->sa_family == AF_INET6))
     526                        continue;
     527               
     528                CHECK_FCT(fd_ep_add_merge( list, cur->ifa_addr, sSAlen(cur->ifa_addr), EP_FL_LL ));
     529        }
     530       
     531        freeifaddrs(iflist);
     532       
     533        return 0;
    533534}
    534535
  • freeDiameter/cnxctx.h

    r258 r378  
    137137#endif /* DISABLE_SCTP */
    138138
     139/* UDP */
     140int fd_cnx_get_local_eps(struct fd_list * list);
     141
    139142#endif /* _CNXCTX_H */
    140143
  • freeDiameter/fD.h

    r304 r378  
    327327int             fd_cnx_getTLS(struct cnxctx * conn);
    328328int             fd_cnx_getcred(struct cnxctx * conn, const gnutls_datum_t **cert_list, unsigned int *cert_list_size);
    329 int             fd_cnx_getendpoints(struct cnxctx * conn, struct fd_list * local, struct fd_list * remote);
     329int             fd_cnx_getremoteeps(struct cnxctx * conn, struct fd_list * eps);
    330330char *          fd_cnx_getremoteid(struct cnxctx * conn);
    331331int             fd_cnx_receive(struct cnxctx * conn, struct timespec * timeout, unsigned char **buf, size_t * len);
  • freeDiameter/p_ce.c

    r332 r378  
    6363       
    6464        /* Read the endpoints, maybe used to reconnect to the peer later */
    65         CHECK_FCT( fd_cnx_getendpoints(peer->p_cnxctx, NULL, &peer->p_hdr.info.pi_endpoints) );
     65        CHECK_FCT( fd_cnx_getremoteeps(peer->p_cnxctx, &peer->p_hdr.info.pi_endpoints) );
    6666       
    6767        /* Read the protocol */
     
    106106        struct avp * avp = NULL;
    107107        union avp_value val;
    108         struct fd_list *li, local_ep = FD_LIST_INITIALIZER(local_ep);
     108        struct fd_list *li;
    109109       
    110110        /* Add the Origin-* AVPs */
     
    114114        CHECK_FCT(  fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Host-IP-Address", &dictobj, ENOENT )  );
    115115               
    116         /* Get the list of endpoints */
    117         CHECK_FCT(  fd_cnx_getendpoints(cnx, &local_ep, NULL) );
    118        
    119116        /* Add the AVP(s) -- not sure what is the purpose... We could probably only add the primary one ? */
    120         for (li = local_ep.next; li != &local_ep; li = li->next) {
     117        for (li = fd_g_config->cnf_endpoints.next; li != &fd_g_config->cnf_endpoints; li = li->next) {
    121118                struct fd_endpoint * ep = (struct fd_endpoint *)li;
    122119               
     
    125122                CHECK_FCT( fd_msg_avp_add( msg, MSG_BRW_LAST_CHILD, avp ) );
    126123        }
    127        
    128124       
    129125        /* Vendor-Id, Product-Name, and Firmware-Revision AVPs */
  • freeDiameter/p_psm.c

    r373 r378  
    571571               
    572572                /* Get the new ones */
    573                 CHECK_FCT_DO( fd_cnx_getendpoints(peer->p_cnxctx, NULL, &peer->p_hdr.info.pi_endpoints), /* ignore the error */);
    574                
    575                 /* We do not support local endpoints change currently, but it could be added here if needed */
     573                CHECK_FCT_DO( fd_cnx_getremoteeps(peer->p_cnxctx, &peer->p_hdr.info.pi_endpoints), /* ignore the error */);
     574               
     575                /* We do not support local endpoints change currently, but it could be added here if needed (refresh fd_g_config->cnf_endpoints)*/
    576576               
    577577                if (TRACE_BOOL(ANNOYING)) {
  • freeDiameter/sctp.c

    r258 r378  
    933933}
    934934
    935 /* Get the list of local endpoints of the socket */
    936 int fd_sctp_get_local_ep(int sock, struct fd_list * list)
    937 {
    938         union {
    939                 sSA     *sa;
    940                 uint8_t *buf;
    941         } ptr;
    942        
    943         sSA * data = NULL;
    944         int count;
    945        
    946         TRACE_ENTRY("%d %p", sock, list);
    947         CHECK_PARAMS(list);
    948        
    949         /* Read the list on the socket */
    950         CHECK_SYS( count = sctp_getladdrs(sock, 0, &data)  );
    951         ptr.sa = data;
    952        
    953         while (count) {
    954                 socklen_t sl;
    955                 switch (ptr.sa->sa_family) {
    956                         case AF_INET:   sl = sizeof(sSA4); break;
    957                         case AF_INET6:  sl = sizeof(sSA6); break;
    958                         default:
    959                                 TRACE_DEBUG(INFO, "Unknown address family returned in sctp_getladdrs: %d", ptr.sa->sa_family);
    960                                 goto stop;
    961                 }
    962                                
    963                 CHECK_FCT( fd_ep_add_merge( list, ptr.sa, sl, EP_FL_LL ) );
    964                 ptr.buf += sl;
    965                 count --;
    966         }
    967 stop:
    968         /* Free the list */
    969         sctp_freeladdrs(data);
    970        
    971         /* Now get the primary address, the add function will take care of merging with existing entry */
    972         {
    973                 sSS ss;
    974                 socklen_t sl = sizeof(sSS);
    975        
    976                 CHECK_SYS(getsockname(sock, (sSA *)&ss, &sl));
    977                 CHECK_FCT( fd_ep_add_merge( list, (sSA *)&ss, sl, EP_FL_PRIMARY ) );
    978         }
    979        
    980         return 0;
    981 }
    982 
    983935/* Get the list of remote endpoints of the socket */
    984936int fd_sctp_get_remote_ep(int sock, struct fd_list * list)
  • freeDiameter/server.c

    r258 r378  
    270270                CHECK_POSIX( pthread_create( &s->thr, NULL, serv_th, s ) );
    271271               
    272                 /* Retrieve the list of endpoints if it was empty */
    273                 if (empty_conf_ep) {
    274                         (void) fd_cnx_getendpoints(s->conn, &fd_g_config->cnf_endpoints, NULL);
    275                         if (TRACE_BOOL(FULL)){
    276                                 fd_log_debug("  Local server address(es) :\n");
    277                                 fd_ep_dump( 5, &fd_g_config->cnf_endpoints );
    278                         }
    279                 }
    280                
    281272                /* Create the server on secure port */
    282273                CHECK_MALLOC( s = new_serv(IPPROTO_SCTP, 1) );
     
    344335        }
    345336       
     337        /* Now, if we still have not got the list of local adresses, try to read it from the kernel directly */
     338        if (FD_IS_LIST_EMPTY(&fd_g_config->cnf_endpoints)) {
     339                CHECK_FCT(fd_cnx_get_local_eps(&fd_g_config->cnf_endpoints));
     340                if (FD_IS_LIST_EMPTY(&fd_g_config->cnf_endpoints)) {
     341                        TRACE_DEBUG(INFO, "Unable to find the addresses of the local system. Please use \"ListenOn\" parameter in the configuration.");
     342                        return EINVAL;
     343                }
     344        }
     345        if (TRACE_BOOL(FULL)){
     346                fd_log_debug("  Local server address(es) :\n");
     347                fd_ep_dump( 5, &fd_g_config->cnf_endpoints );
     348        }
    346349        return 0;
    347350}
  • freeDiameter/tcp.c

    r258 r378  
    170170}
    171171
    172 
    173 /* Get the local name of a TCP socket -- would be nice if it did not return "0.0.0.0"... */
    174 int fd_tcp_get_local_ep(int sock, sSS * ss, socklen_t *sl)
    175 {
    176         TRACE_ENTRY("%d %p %p", sock, ss, sl);
    177         CHECK_PARAMS( ss && sl );
    178        
    179         *sl = sizeof(sSS);
    180         CHECK_SYS(getsockname(sock, (sSA *)ss, sl));
    181        
    182         return 0;
    183 }
    184 
    185172/* Get the remote name of a TCP socket */
    186173int fd_tcp_get_remote_ep(int sock, sSS * ss, socklen_t *sl)
     
    194181        return 0;
    195182}
     183
  • include/freeDiameter/CMakeLists.txt

    r316 r378  
    4343CHECK_INCLUDE_FILES (malloc.h HAVE_MALLOC_H)
    4444
     45# getifaddrs ?
     46CHECK_FUNCTION_EXISTS (getifaddrs HAVE_GETIFADDRS)
     47IF (NOT HAVE_GETIFADDRS)
     48   MESSAGE(SEND_ERROR "The getifaddrs function is currently required by freeDiameter.")
     49ENDIF (NOT HAVE_GETIFADDRS)
    4550
    4651# pthreads
Note: See TracChangeset for help on using the changeset viewer.