Navigation


Changeset 23:db6c40b8b307 in freeDiameter


Ignore:
Timestamp:
Oct 20, 2009, 5:30:20 PM (15 years ago)
Author:
Sebastien Decugis <sdecugis@nict.go.jp>
Branch:
default
Phase:
public
Message:

Added some code in cnxctx.c mainly

Files:
12 edited

Legend:

Unmodified
Added
Removed
  • doc/freediameter.conf.sample

    r22 r23  
    6868#ListenOn = "202.249.37.5";
    6969#ListenOn = "2001:200:903:2::202:1";
     70#ListenOn = "fe80::21c:5ff:fe98:7d62%eth0";
    7071
    7172##############################################################
     
    201202SecPort = 3867;
    202203TLS_old_method;
    203 No_SCTP;
    204 Prefer_TCP;
    205204SCTP_streams = 50;
    206 #ListenOn = "202.249.37.5";
    207 #ListenOn = "2001:200:903:2::202:1";
    208205TcTimer = 60;
    209206TwTimer = 6;
     207ListenOn = "133.243.146.201";
     208ListenOn = "fe80::21d:9ff:fe89:7d68%eth0";
    210209NoRelay;
    211210LoadExtension = "extensions/dbg_monitor.fdx";
  • freeDiameter/cnxctx.c

    r22 r23  
    214214                        break;
    215215
     216#ifndef DISABLE_SCTP
    216217                case IPPROTO_SCTP:
    217218                        CHECK_FCT(fd_sctp_listen(conn->cc_socket));
    218219                        break;
     220#endif /* DISABLE_SCTP */
    219221
    220222                default:
     
    400402}
    401403
    402 /* Get the list of endpoints (IP addresses) of the local and remote peers on this conenction */
     404/* Get the list of endpoints (IP addresses) of the local and remote peers on this connection */
    403405int fd_cnx_getendpoints(struct cnxctx * conn, struct fd_list * local, struct fd_list * remote)
    404406{
     
    408410        if (local) {
    409411                /* Retrieve the local endpoint(s) of the connection */
    410                 TODO("TCP : getsockname");
    411                 TODO("SCTP: sctp_getladdrs / _sctp_getboundaddrs (waaad)");
     412                switch (conn->cc_proto) {
     413                        case IPPROTO_TCP: {
     414                                sSS ss;
     415                                socklen_t sl;
     416                                CHECK_FCT(fd_tcp_get_local_ep(conn->cc_socket, &ss, &sl));
     417                                CHECK_FCT(fd_ep_add_merge( local, (sSA *)&ss, sl, 0, 0, 0, 1 ));
     418                        }
     419                        break;
     420
     421                        #ifndef DISABLE_SCTP
     422                        case IPPROTO_SCTP: {
     423                                CHECK_FCT(fd_sctp_get_local_ep(conn->cc_socket, local));
     424                        }
     425                        break;
     426                        #endif /* DISABLE_SCTP */
     427
     428                        default:
     429                                CHECK_PARAMS(0);
     430                }
    412431        }
    413432       
    414433        if (remote) {
     434                /* Check we have a full connection object, not a listening socket (with no remote) */
     435                CHECK_PARAMS( conn->cc_events );
     436               
    415437                /* Retrieve the peer endpoint(s) of the connection */
    416                 TODO("TCP : getpeername");
    417                 TODO("SCTP: sctp_getpaddrs");
    418                
    419         }
    420 
    421         return ENOTSUP;
     438                switch (conn->cc_proto) {
     439                        case IPPROTO_TCP: {
     440                                sSS ss;
     441                                socklen_t sl;
     442                                CHECK_FCT(fd_tcp_get_remote_ep(conn->cc_socket, &ss, &sl));
     443                                CHECK_FCT(fd_ep_add_merge( remote, (sSA *)&ss, sl, 0, 0, 0, 1 ));
     444                        }
     445                        break;
     446
     447                        #ifndef DISABLE_SCTP
     448                        case IPPROTO_SCTP: {
     449                                CHECK_FCT(fd_sctp_get_remote_ep(conn->cc_socket, remote));
     450                        }
     451                        break;
     452                        #endif /* DISABLE_SCTP */
     453
     454                        default:
     455                                CHECK_PARAMS(0);
     456                }
     457        }
     458
     459        return 0;
    422460}
    423461
  • freeDiameter/config.c

    r22 r23  
    100100                        struct fd_endpoint * ep = (struct fd_endpoint *)li;
    101101                        if (li != fd_g_config->cnf_endpoints.next) fd_log_debug("                             ");
    102                         sSA_DUMP_NODE( &ep->ss, NI_NUMERICHOST );
     102                        sSA_DUMP_NODE( &ep->sa, NI_NUMERICHOST );
    103103                        fd_log_debug("\n");
    104104                        li = li->next;
     
    234234                for ( li = fd_g_config->cnf_endpoints.next; li != &fd_g_config->cnf_endpoints; li = li->next) {
    235235                        struct fd_endpoint * ep = (struct fd_endpoint *)li;
    236                         if ( (fd_g_config->cnf_flags.no_ip4 && (ep->ss.ss_family == AF_INET))
    237                            ||(fd_g_config->cnf_flags.no_ip6 && (ep->ss.ss_family == AF_INET6)) ) {
     236                        if ( (fd_g_config->cnf_flags.no_ip4 && (ep->sa.sa_family == AF_INET))
     237                           ||(fd_g_config->cnf_flags.no_ip6 && (ep->sa.sa_family == AF_INET6)) ) {
    238238                                li = li->prev;
    239239                                fd_list_unlink(&ep->chain);
    240240                                if (TRACE_BOOL(INFO)) {
    241241                                        fd_log_debug("Info: Removing local address conflicting with the flags no_IP / no_IP6 : ");
    242                                         sSA_DUMP_NODE( &ep->ss, AI_NUMERICHOST );
     242                                        sSA_DUMP_NODE( &ep->sa, AI_NUMERICHOST );
    243243                                        fd_log_debug("\n");
    244244                                }
     
    272272        return 0;
    273273}
     274
     275/* Add an endpoint information in a list */
     276int fd_ep_add_merge( struct fd_list * list, sSA * sa, socklen_t sl, int conf, int disc, int adv, int ll )
     277{
     278        struct fd_endpoint * ep;
     279        struct fd_list * li;
     280        int cmp = -1;
     281       
     282        TRACE_ENTRY("%p %p %u %i %i %i %i", list, sa, sl, conf, disc, adv, ll);
     283        CHECK_PARAMS( list && sa && (sl <= sizeof(sSS)) && (conf || disc || adv || ll) );
     284       
     285        /* Search place in the list */
     286        for (li = list->next; li != list; li = li->next) {
     287                ep = (struct fd_endpoint *)li;
     288               
     289                cmp = memcmp(&ep->ss, sa, sl);
     290                if (cmp >= 0)
     291                        break;
     292        }
     293       
     294        if (cmp) {
     295                /* new item to be added */
     296                CHECK_MALLOC( ep = malloc(sizeof(struct fd_endpoint)) );
     297                memset(ep, 0, sizeof(struct fd_endpoint));
     298                fd_list_init(&ep->chain, NULL);
     299                memcpy(&ep->ss, sa, sl);
     300               
     301                /* Insert in the list */
     302                fd_list_insert_before(li, &ep->chain);
     303        }
     304       
     305        /* Merge the flags */
     306        ep->meta.conf = conf || ep->meta.conf;
     307        ep->meta.disc = disc || ep->meta.disc;
     308        ep->meta.adv  =  adv || ep->meta.adv;
     309        ep->meta.ll   =   ll || ep->meta.ll;
     310       
     311        return 0;
     312}
     313
  • freeDiameter/fD.h

    r22 r23  
    222222int fd_tcp_create_bind_server( int * sock, sSA * sa, socklen_t salen );
    223223int fd_tcp_listen( int sock );
     224int fd_tcp_get_local_ep(int sock, sSS * ss, socklen_t *sl);
     225int fd_tcp_get_remote_ep(int sock, sSS * ss, socklen_t *sl);
    224226
    225227/* SCTP */
     
    227229int fd_sctp_create_bind_server( int * sock, struct fd_list * list, uint16_t port );
    228230int fd_sctp_listen( int sock );
    229 
     231int fd_sctp_get_local_ep(int sock, struct fd_list * list);
     232int fd_sctp_get_remote_ep(int sock, struct fd_list * list);
    230233int fd_sctp_get_str_info( int socket, int *in, int *out );
    231234
  • freeDiameter/fdd.y

    r22 r23  
    212212listenon:               LISTENON '=' QSTRING ';'
    213213                        {
    214                                 struct fd_endpoint * ep;
    215214                                struct addrinfo hints, *ai;
    216215                                int ret;
    217                                
    218                                 CHECK_MALLOC_DO( ep = malloc(sizeof(struct fd_endpoint)),
    219                                         { yyerror (&yylloc, conf, "Out of memory"); YYERROR; } );
    220                                 memset(ep, 0, sizeof(struct fd_endpoint));
    221                                 fd_list_init(&ep->chain, NULL);
    222                                 ep->meta.conf = 1;
    223216                               
    224217                                memset(&hints, 0, sizeof(hints));
    225218                                hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;
    226219                                ret = getaddrinfo($3, NULL, &hints, &ai);
    227                                 if (ret) { yyerror (&yylloc, conf, gai_strerror(ret)); free(ep); YYERROR; }
    228                                 ASSERT( ai->ai_addrlen <= sizeof(sSS) );
    229                                 memcpy(&ep->ss, ai->ai_addr, ai->ai_addrlen);
     220                                if (ret) { yyerror (&yylloc, conf, gai_strerror(ret)); YYERROR; }
     221                                CHECK_FCT_DO( fd_ep_add_merge( &conf->cnf_endpoints, ai->ai_addr, ai->ai_addrlen, 1, 0, 0, 0 ), YYERROR );
     222                                freeaddrinfo(ai);
    230223                                free($3);
    231                                 freeaddrinfo(ai);
    232                                 fd_list_insert_before(&conf->cnf_endpoints, &ep->chain);
    233224                        }
    234225                        ;
     
    430421                        | peerparams CONNTO '=' QSTRING ';'
    431422                        {
    432                                 struct fd_endpoint * ep;
    433423                                struct addrinfo hints, *ai;
    434424                                int ret;
     425                                int disc = 0;
    435426                               
    436                                 CHECK_MALLOC_DO( ep = malloc(sizeof(struct fd_endpoint)),
    437                                         { yyerror (&yylloc, conf, "Out of memory"); YYERROR; } );
    438                                 memset(ep, 0, sizeof(struct fd_endpoint));
    439                                 fd_list_init(&ep->chain, NULL);
    440                                 ep->meta.conf = 1;
    441427                                memset(&hints, 0, sizeof(hints));
    442428                                hints.ai_flags = AI_ADDRCONFIG | AI_NUMERICHOST;
     
    444430                                if (ret == EAI_NONAME) {
    445431                                        /* The name was maybe not numeric, try again */
    446                                         ep->meta.disc = 1;
     432                                        disc = 1;
    447433                                        hints.ai_flags &= ~ AI_NUMERICHOST;
    448434                                        ret = getaddrinfo($4, NULL, &hints, &ai);
    449435                                }
    450                                 if (ret) { yyerror (&yylloc, conf, gai_strerror(ret)); free(ep); YYERROR; }
     436                                if (ret) { yyerror (&yylloc, conf, gai_strerror(ret)); YYERROR; }
    451437                               
    452                                 memcpy(&ep->ss, ai->ai_addr, ai->ai_addrlen);
     438                                CHECK_FCT_DO( fd_ep_add_merge( &fddpi.pi_endpoints, ai->ai_addr, ai->ai_addrlen, 1, disc, 0, 0 ), YYERROR );
    453439                                free($4);
    454440                                freeaddrinfo(ai);
    455                                 fd_list_insert_before(&fddpi.pi_endpoints, &ep->chain);
    456441                        }
    457442                        ;
  • freeDiameter/main.c

    r22 r23  
    106106        CHECK_FCT(  fd_ext_load()  );
    107107       
     108        fd_conf_dump();
     109       
    108110        /* Start the servers */
    109111        CHECK_FCT( fd_servers_start() );
     
    114116        /* Now, just wait for events */
    115117        TRACE_DEBUG(INFO, FD_PROJECT_BINARY " daemon initialized.");
    116         fd_conf_dump();
    117118        while (1) {
    118119                int code;
  • freeDiameter/sctp.c

    r22 r23  
    3535
    3636#include "fD.h"
     37#include <netinet/sctp.h>
     38#include <sys/uio.h>
     39
     40/* Pre-binding socket options -- # streams read in config */
     41static int fd_setsockopt_prebind(int sk)
     42{
     43        #ifdef DEBUG_SCTP
     44        socklen_t sz;
     45        #endif /* DEBUG_SCTP */
     46       
     47        TRACE_ENTRY( "%d", sk);
     48       
     49        CHECK_PARAMS( sk > 0 );
     50       
     51        /* Subscribe to some notifications */
     52        {
     53                struct sctp_event_subscribe event;
     54
     55                memset(&event, 0, sizeof(event));
     56                event.sctp_data_io_event        = 1;    /* to receive the stream ID in SCTP_SNDRCV ancilliary data on message reception */
     57                event.sctp_association_event    = 0;    /* new or closed associations (mostly for one-to-many style sockets) */
     58                event.sctp_address_event        = 1;    /* address changes */
     59                event.sctp_send_failure_event   = 1;    /* delivery failures */
     60                event.sctp_peer_error_event     = 1;    /* remote peer sends an error */
     61                event.sctp_shutdown_event       = 1;    /* peer has sent a SHUTDOWN */
     62                event.sctp_partial_delivery_event = 1;  /* a partial delivery is aborted, probably indicating the connection is being shutdown */
     63                // event.sctp_adaptation_layer_event = 0;       /* adaptation layer notifications */
     64                // event.sctp_authentication_event = 0; /* when new key is made active */
     65
     66                /* Set the option to the socket */
     67                CHECK_SYS(  setsockopt(sk, IPPROTO_SCTP, SCTP_EVENTS, &event, sizeof(event)) );
     68               
     69                #ifdef DEBUG_SCTP
     70                sz = sizeof(event);
     71                CHECK_SYS(  getsockopt(sk, IPPROTO_SCTP, SCTP_EVENTS, &event, &sz) );
     72                if (sz != sizeof(event))
     73                {
     74                        TRACE_DEBUG(INFO, "Invalid size of socket option: %d / %d", sz, (socklen_t)sizeof(event));
     75                        return ENOTSUP;
     76                }
     77               
     78                TRACE_DEBUG(FULL, "SCTP_EVENTS sctp_data_io_event          : %hhu", event.sctp_data_io_event);
     79                TRACE_DEBUG(FULL, "SCTP_EVENTS sctp_association_event      : %hhu", event.sctp_association_event);
     80                TRACE_DEBUG(FULL, "SCTP_EVENTS sctp_address_event          : %hhu", event.sctp_address_event);
     81                TRACE_DEBUG(FULL, "SCTP_EVENTS sctp_send_failure_event     : %hhu", event.sctp_send_failure_event);
     82                TRACE_DEBUG(FULL, "SCTP_EVENTS sctp_peer_error_event       : %hhu", event.sctp_peer_error_event);
     83                TRACE_DEBUG(FULL, "SCTP_EVENTS sctp_shutdown_event         : %hhu", event.sctp_shutdown_event);
     84                TRACE_DEBUG(FULL, "SCTP_EVENTS sctp_partial_delivery_event : %hhu", event.sctp_partial_delivery_event);
     85                TRACE_DEBUG(FULL, "SCTP_EVENTS sctp_adaptation_layer_event : %hhu", event.sctp_adaptation_layer_event);
     86                // TRACE_DEBUG(FULL, "SCTP_EVENTS sctp_authentication_event   : %hhu", event.sctp_authentication_event);
     87                #endif /* DEBUG_SCTP */
     88               
     89        }
     90       
     91        /* Set the INIT parameters, such as number of streams */
     92        {
     93                struct sctp_initmsg init;
     94                memset(&init, 0, sizeof(init));
     95               
     96                #ifdef DEBUG_SCTP
     97                sz = sizeof(init);
     98               
     99                /* Read socket defaults */
     100                CHECK_SYS(  getsockopt(sk, IPPROTO_SCTP, SCTP_INITMSG, &init, &sz)  );
     101                if (sz != sizeof(init))
     102                {
     103                        TRACE_DEBUG(INFO, "Invalid size of socket option: %d / %d", sz, (socklen_t)sizeof(init));
     104                        return ENOTSUP;
     105                }
     106                TRACE_DEBUG(FULL, "Def SCTP_INITMSG sinit_num_ostreams   : %hu", init.sinit_num_ostreams);
     107                TRACE_DEBUG(FULL, "Def SCTP_INITMSG sinit_max_instreams  : %hu", init.sinit_max_instreams);
     108                TRACE_DEBUG(FULL, "Def SCTP_INITMSG sinit_max_attempts   : %hu", init.sinit_max_attempts);
     109                TRACE_DEBUG(FULL, "Def SCTP_INITMSG sinit_max_init_timeo : %hu", init.sinit_max_init_timeo);
     110                #endif /* DEBUG_SCTP */
     111
     112                /* Set the init options -- need to receive SCTP_COMM_UP to confirm the requested parameters */
     113                init.sinit_num_ostreams   = fd_g_config->cnf_sctp_str;  /* desired number of outgoing streams */
     114                init.sinit_max_init_timeo = CNX_TIMEOUT * 1000;
     115
     116                /* Set the option to the socket */
     117                CHECK_SYS(  setsockopt(sk, IPPROTO_SCTP, SCTP_INITMSG, &init, sizeof(init))  );
     118               
     119                #ifdef DEBUG_SCTP
     120                /* Check new values */
     121                CHECK_SYS(  getsockopt(sk, IPPROTO_SCTP, SCTP_INITMSG, &init, &sz)  );
     122                TRACE_DEBUG(FULL, "New SCTP_INITMSG sinit_num_ostreams   : %hu", init.sinit_num_ostreams);
     123                TRACE_DEBUG(FULL, "New SCTP_INITMSG sinit_max_instreams  : %hu", init.sinit_max_instreams);
     124                TRACE_DEBUG(FULL, "New SCTP_INITMSG sinit_max_attempts   : %hu", init.sinit_max_attempts);
     125                TRACE_DEBUG(FULL, "New SCTP_INITMSG sinit_max_init_timeo : %hu", init.sinit_max_init_timeo);
     126                #endif /* DEBUG_SCTP */
     127        }
     128       
     129        /* Set the SCTP_DISABLE_FRAGMENTS option, required for TLS */
     130        #ifdef SCTP_DISABLE_FRAGMENTS
     131        {
     132                int nofrag;
     133               
     134                #ifdef DEBUG_SCTP
     135                sz = sizeof(nofrag);
     136                /* Read socket defaults */
     137                CHECK_SYS(  getsockopt(sk, IPPROTO_SCTP, SCTP_DISABLE_FRAGMENTS, &nofrag, &sz)  );
     138                if (sz != sizeof(nofrag))
     139                {
     140                        TRACE_DEBUG(INFO, "Invalid size of socket option: %d / %d", sz, (socklen_t)sizeof(nofrag));
     141                        return ENOTSUP;
     142                }
     143                TRACE_DEBUG(FULL, "Def SCTP_DISABLE_FRAGMENTS value : %s", nofrag ? "true" : "false");
     144                #endif /* DEBUG_SCTP */
     145
     146                nofrag = 0;     /* We turn ON the fragmentation */
     147               
     148                /* Set the option to the socket */
     149                CHECK_SYS(  setsockopt(sk, IPPROTO_SCTP, SCTP_DISABLE_FRAGMENTS, &nofrag, sizeof(nofrag))  );
     150               
     151                #ifdef DEBUG_SCTP
     152                /* Check new values */
     153                CHECK_SYS(  getsockopt(sk, IPPROTO_SCTP, SCTP_DISABLE_FRAGMENTS, &nofrag, &sz)  );
     154                TRACE_DEBUG(FULL, "New SCTP_DISABLE_FRAGMENTS value : %s", nofrag ? "true" : "false");
     155                #endif /* DEBUG_SCTP */
     156        }
     157        #else /* SCTP_DISABLE_FRAGMENTS */
     158        # error "TLS requires support of SCTP_DISABLE_FRAGMENTS"
     159        #endif /* SCTP_DISABLE_FRAGMENTS */
     160       
     161       
     162        /* Set the RETRANSMIT parameters */
     163        #ifdef SCTP_RTOINFO
     164        {
     165                struct sctp_rtoinfo rtoinfo;
     166                memset(&rtoinfo, 0, sizeof(rtoinfo));
     167
     168                #ifdef DEBUG_SCTP
     169                sz = sizeof(rtoinfo);
     170                /* Read socket defaults */
     171                CHECK_SYS(  getsockopt(sk, IPPROTO_SCTP, SCTP_RTOINFO, &rtoinfo, &sz)  );
     172                if (sz != sizeof(rtoinfo))
     173                {
     174                        TRACE_DEBUG(INFO, "Invalid size of socket option: %d / %d", sz, (socklen_t)sizeof(rtoinfo));
     175                        return ENOTSUP;
     176                }
     177                TRACE_DEBUG(FULL, "Def SCTP_RTOINFO srto_initial : %u", rtoinfo.srto_initial);
     178                TRACE_DEBUG(FULL, "Def SCTP_RTOINFO srto_max     : %u", rtoinfo.srto_max);
     179                TRACE_DEBUG(FULL, "Def SCTP_RTOINFO srto_min     : %u", rtoinfo.srto_min);
     180                #endif /* DEBUG_SCTP */
     181
     182                rtoinfo.srto_max     = fd_g_config->cnf_timer_tw * 500 - 1000;  /* Maximum retransmit timer (in ms) (set to Tw / 2 - 1) */
     183
     184                /* Set the option to the socket */
     185                CHECK_SYS(  setsockopt(sk, IPPROTO_SCTP, SCTP_RTOINFO, &rtoinfo, sizeof(rtoinfo))  );
     186               
     187                #ifdef DEBUG_SCTP
     188                /* Check new values */
     189                CHECK_SYS(  getsockopt(sk, IPPROTO_SCTP, SCTP_RTOINFO, &rtoinfo, &sz)  );
     190                TRACE_DEBUG(FULL, "New SCTP_RTOINFO srto_initial : %u", rtoinfo.srto_initial);
     191                TRACE_DEBUG(FULL, "New SCTP_RTOINFO srto_max     : %u", rtoinfo.srto_max);
     192                TRACE_DEBUG(FULL, "New SCTP_RTOINFO srto_min     : %u", rtoinfo.srto_min);
     193                #endif /* DEBUG_SCTP */
     194        }
     195        #else /* SCTP_RTOINFO */
     196        # ifdef DEBUG_SCTP
     197        TRACE_DEBUG(FULL, "Skipping SCTP_RTOINFO");
     198        # endif /* DEBUG_SCTP */
     199        #endif /* SCTP_RTOINFO */
     200       
     201        /* Set the ASSOCIATION parameters */
     202        #ifdef SCTP_ASSOCINFO
     203        {
     204                struct sctp_assocparams assoc;
     205                memset(&assoc, 0, sizeof(assoc));
     206
     207                #ifdef DEBUG_SCTP
     208                sz = sizeof(assoc);
     209                /* Read socket defaults */
     210                CHECK_SYS(  getsockopt(sk, IPPROTO_SCTP, SCTP_ASSOCINFO, &assoc, &sz)  );
     211                if (sz != sizeof(assoc))
     212                {
     213                        TRACE_DEBUG(INFO, "Invalid size of socket option: %d / %d", sz, (socklen_t)sizeof(assoc));
     214                        return ENOTSUP;
     215                }
     216                TRACE_DEBUG(FULL, "Def SCTP_ASSOCINFO sasoc_asocmaxrxt               : %hu", assoc.sasoc_asocmaxrxt);
     217                TRACE_DEBUG(FULL, "Def SCTP_ASSOCINFO sasoc_number_peer_destinations : %hu", assoc.sasoc_number_peer_destinations);
     218                TRACE_DEBUG(FULL, "Def SCTP_ASSOCINFO sasoc_peer_rwnd                : %u" , assoc.sasoc_peer_rwnd);
     219                TRACE_DEBUG(FULL, "Def SCTP_ASSOCINFO sasoc_local_rwnd               : %u" , assoc.sasoc_local_rwnd);
     220                TRACE_DEBUG(FULL, "Def SCTP_ASSOCINFO sasoc_cookie_life              : %u" , assoc.sasoc_cookie_life);
     221                #endif /* DEBUG_SCTP */
     222
     223                assoc.sasoc_asocmaxrxt = 5;     /* Maximum retransmission attempts: we want fast detection of errors */
     224               
     225                /* Set the option to the socket */
     226                CHECK_SYS(  setsockopt(sk, IPPROTO_SCTP, SCTP_ASSOCINFO, &assoc, sizeof(assoc))  );
     227               
     228                #ifdef DEBUG_SCTP
     229                /* Check new values */
     230                CHECK_SYS(  getsockopt(sk, IPPROTO_SCTP, SCTP_ASSOCINFO, &assoc, &sz)  );
     231                TRACE_DEBUG(FULL, "New SCTP_ASSOCINFO sasoc_asocmaxrxt               : %hu", assoc.sasoc_asocmaxrxt);
     232                TRACE_DEBUG(FULL, "New SCTP_ASSOCINFO sasoc_number_peer_destinations : %hu", assoc.sasoc_number_peer_destinations);
     233                TRACE_DEBUG(FULL, "New SCTP_ASSOCINFO sasoc_peer_rwnd                : %u" , assoc.sasoc_peer_rwnd);
     234                TRACE_DEBUG(FULL, "New SCTP_ASSOCINFO sasoc_local_rwnd               : %u" , assoc.sasoc_local_rwnd);
     235                TRACE_DEBUG(FULL, "New SCTP_ASSOCINFO sasoc_cookie_life              : %u" , assoc.sasoc_cookie_life);
     236                #endif /* DEBUG_SCTP */
     237        }
     238        #else /* SCTP_ASSOCINFO */
     239        # ifdef DEBUG_SCTP
     240        TRACE_DEBUG(FULL, "Skipping SCTP_ASSOCINFO");
     241        # endif /* DEBUG_SCTP */
     242        #endif /* SCTP_ASSOCINFO */
     243       
     244       
     245        /* The SO_LINGER option will be re-set if we want to perform SCTP ABORT */
     246        #ifdef SO_LINGER
     247        {
     248                struct linger linger;
     249                memset(&linger, 0, sizeof(linger));
     250               
     251                #ifdef DEBUG_SCTP
     252                sz = sizeof(linger);
     253                /* Read socket defaults */
     254                CHECK_SYS(  getsockopt(sk, SOL_SOCKET, SO_LINGER, &linger, &sz)  );
     255                if (sz != sizeof(linger))
     256                {
     257                        TRACE_DEBUG(INFO, "Invalid size of socket option: %d / %d", sz, (socklen_t)sizeof(linger));
     258                        return ENOTSUP;
     259                }
     260                TRACE_DEBUG(FULL, "Def SO_LINGER l_onoff  : %d", linger.l_onoff);
     261                TRACE_DEBUG(FULL, "Def SO_LINGER l_linger : %d", linger.l_linger);
     262                #endif /* DEBUG_SCTP */
     263               
     264                linger.l_onoff  = 0;    /* Do not activate the linger */
     265                linger.l_linger = 0;    /* Return immediately when closing (=> abort) */
     266               
     267                /* Set the option */
     268                CHECK_SYS(  setsockopt(sk, SOL_SOCKET, SO_LINGER, &linger, sizeof(linger))  );
     269               
     270                #ifdef DEBUG_SCTP
     271                /* Check new values */
     272                CHECK_SYS(  getsockopt(sk, SOL_SOCKET, SO_LINGER, &linger, &sz)  );
     273                TRACE_DEBUG(FULL, "New SO_LINGER l_onoff  : %d", linger.l_onoff);
     274                TRACE_DEBUG(FULL, "New SO_LINGER l_linger : %d", linger.l_linger);
     275                #endif /* DEBUG_SCTP */
     276        }
     277        #else /* SO_LINGER */
     278        # ifdef DEBUG_SCTP
     279        TRACE_DEBUG(FULL, "Skipping SO_LINGER");
     280        # endif /* DEBUG_SCTP */
     281        #endif /* SO_LINGER */
     282       
     283        /* Set the NODELAY option (Nagle-like algorithm) */
     284        #ifdef SCTP_NODELAY
     285        {
     286                int nodelay;
     287               
     288                #ifdef DEBUG_SCTP
     289                sz = sizeof(nodelay);
     290                /* Read socket defaults */
     291                CHECK_SYS(  getsockopt(sk, IPPROTO_SCTP, SCTP_NODELAY, &nodelay, &sz)  );
     292                if (sz != sizeof(nodelay))
     293                {
     294                        TRACE_DEBUG(INFO, "Invalid size of socket option: %d / %d", sz, (socklen_t)sizeof(nodelay));
     295                        return ENOTSUP;
     296                }
     297                TRACE_DEBUG(FULL, "Def SCTP_NODELAY value : %s", nodelay ? "true" : "false");
     298                #endif /* DEBUG_SCTP */
     299
     300                nodelay = 0;    /* We turn ON the Nagle algorithm (probably the default already) */
     301               
     302                /* Set the option to the socket */
     303                CHECK_SYS(  setsockopt(sk, IPPROTO_SCTP, SCTP_NODELAY, &nodelay, sizeof(nodelay))  );
     304               
     305                #ifdef DEBUG_SCTP
     306                /* Check new values */
     307                CHECK_SYS(  getsockopt(sk, IPPROTO_SCTP, SCTP_NODELAY, &nodelay, &sz)  );
     308                TRACE_DEBUG(FULL, "New SCTP_NODELAY value : %s", nodelay ? "true" : "false");
     309                #endif /* DEBUG_SCTP */
     310        }
     311        #else /* SCTP_NODELAY */
     312        # ifdef DEBUG_SCTP
     313        TRACE_DEBUG(FULL, "Skipping SCTP_NODELAY");
     314        # endif /* DEBUG_SCTP */
     315        #endif /* SCTP_NODELAY */
     316       
     317        /* Set the interleaving option */
     318        #ifdef SCTP_FRAGMENT_INTERLEAVE
     319        {
     320                int interleave;
     321               
     322                #ifdef DEBUG_SCTP
     323                sz = sizeof(interleave);
     324                /* Read socket defaults */
     325                CHECK_SYS(  getsockopt(sk, IPPROTO_SCTP, SCTP_FRAGMENT_INTERLEAVE, &interleave, &sz)  );
     326                if (sz != sizeof(interleave))
     327                {
     328                        TRACE_DEBUG(INFO, "Invalid size of socket option: %d / %d", sz, (socklen_t)sizeof(interleave));
     329                        return ENOTSUP;
     330                }
     331                TRACE_DEBUG(FULL, "Def SCTP_FRAGMENT_INTERLEAVE value : %d", interleave);
     332                #endif /* DEBUG_SCTP */
     333
     334                #if 0
     335                interleave = 2; /* Allow partial delivery on several streams at the same time, since we are stream-aware in our security modules */
     336                #else /* 0 */
     337                interleave = 1; /* hmmm actually, we are not yet capable of handling this, and we don t need it. */
     338                #endif /* 0 */
     339               
     340                /* Set the option to the socket */
     341                CHECK_SYS(  setsockopt(sk, IPPROTO_SCTP, SCTP_FRAGMENT_INTERLEAVE, &interleave, sizeof(interleave))  );
     342               
     343                #ifdef DEBUG_SCTP
     344                /* Check new values */
     345                CHECK_SYS(  getsockopt(sk, IPPROTO_SCTP, SCTP_FRAGMENT_INTERLEAVE, &interleave, &sz)  );
     346                TRACE_DEBUG(FULL, "New SCTP_FRAGMENT_INTERLEAVE value : %d", interleave);
     347                #endif /* DEBUG_SCTP */
     348        }
     349        #else /* SCTP_FRAGMENT_INTERLEAVE */
     350        # ifdef DEBUG_SCTP
     351        TRACE_DEBUG(FULL, "Skipping SCTP_FRAGMENT_INTERLEAVE");
     352        # endif /* DEBUG_SCTP */
     353        #endif /* SCTP_FRAGMENT_INTERLEAVE */
     354       
     355        /* Set the v4 mapped addresses option */
     356        #ifdef SCTP_I_WANT_MAPPED_V4_ADDR
     357        {
     358                int v4mapped;
     359               
     360                #ifdef DEBUG_SCTP
     361                sz = sizeof(v4mapped);
     362                /* Read socket defaults */
     363                CHECK_SYS(  getsockopt(sk, IPPROTO_SCTP, SCTP_I_WANT_MAPPED_V4_ADDR, &v4mapped, &sz)  );
     364                if (sz != sizeof(v4mapped))
     365                {
     366                        TRACE_DEBUG(INFO, "Invalid size of socket option: %d / %d", sz, (socklen_t)sizeof(v4mapped));
     367                        return ENOTSUP;
     368                }
     369                TRACE_DEBUG(FULL, "Def SCTP_I_WANT_MAPPED_V4_ADDR value : %s", v4mapped ? "true" : "false");
     370                #endif /* DEBUG_SCTP */
     371
     372                v4mapped = 0;   /* We don't want v4 mapped addresses */
     373                v4mapped = 1;   /* but we have to, otherwise the bind fails in linux currently ... (Ok, It'd be better with a cmake test, any volunteer?) */
     374               
     375                /* Set the option to the socket */
     376                CHECK_SYS(  setsockopt(sk, IPPROTO_SCTP, SCTP_I_WANT_MAPPED_V4_ADDR, &v4mapped, sizeof(v4mapped))  );
     377               
     378                #ifdef DEBUG_SCTP
     379                /* Check new values */
     380                CHECK_SYS(  getsockopt(sk, IPPROTO_SCTP, SCTP_I_WANT_MAPPED_V4_ADDR, &v4mapped, &sz)  );
     381                TRACE_DEBUG(FULL, "New SCTP_I_WANT_MAPPED_V4_ADDR value : %s", v4mapped ? "true" : "false");
     382                #endif /* DEBUG_SCTP */
     383        }
     384        #else /* SCTP_I_WANT_MAPPED_V4_ADDR */
     385        # ifdef DEBUG_SCTP
     386        TRACE_DEBUG(FULL, "Skipping SCTP_I_WANT_MAPPED_V4_ADDR");
     387        # endif /* DEBUG_SCTP */
     388        #endif /* SCTP_I_WANT_MAPPED_V4_ADDR */
     389                           
     390                           
     391        /* Other settable options (draft-ietf-tsvwg-sctpsocket-17):
     392           SO_RCVBUF                    size of receiver window
     393           SO_SNDBUF                    size of pending data to send
     394           SCTP_AUTOCLOSE               for one-to-many only
     395           SCTP_SET_PEER_PRIMARY_ADDR   ask remote peer to use this local address as primary
     396           SCTP_PRIMARY_ADDR            use this address as primary locally
     397           SCTP_ADAPTATION_LAYER        set adaptation layer indication
     398           SCTP_PEER_ADDR_PARAMS        control heartbeat per peer address
     399           SCTP_DEFAULT_SEND_PARAM      parameters for the sendto() call
     400           SCTP_MAXSEG                  max size of fragmented segments -- bound to PMTU
     401           SCTP_AUTH_CHUNK              request authentication of some type of chunk
     402            SCTP_HMAC_IDENT             authentication algorithms
     403            SCTP_AUTH_KEY               set a shared key
     404            SCTP_AUTH_ACTIVE_KEY        set the active key
     405            SCTP_AUTH_DELETE_KEY        remove a key
     406            SCTP_AUTH_DEACTIVATE_KEY    will not use that key anymore
     407           SCTP_DELAYED_SACK            control delayed acks
     408           SCTP_PARTIAL_DELIVERY_POINT  control partial delivery size
     409           SCTP_USE_EXT_RCVINFO         use extended receive info structure (information about the next message if available)
     410           SCTP_MAX_BURST               number of packets that can be burst emitted
     411           SCTP_CONTEXT                 save a context information along with the association.
     412           SCTP_EXPLICIT_EOR            enable sending one message across several send calls
     413           SCTP_REUSE_PORT              share one listening port with several sockets
     414           
     415           read-only options:
     416           SCTP_STATUS                  retrieve info such as number of streams, pending packets, state, ...
     417           SCTP_GET_PEER_ADDR_INFO      get information about a specific peer address of the association.
     418           SCTP_PEER_AUTH_CHUNKS        list of chunks the remote peer wants authenticated
     419           SCTP_LOCAL_AUTH_CHUNKS       list of chunks the local peer wants authenticated
     420           SCTP_GET_ASSOC_NUMBER        number of associations in a one-to-many socket
     421           SCTP_GET_ASSOC_ID_LIST       list of these associations
     422        */
     423       
     424        /* In case of no_ip4, force the v6only option */
     425        #ifdef IPV6_V6ONLY
     426        if (fd_g_config->cnf_flags.no_ip4) {
     427                int opt = 1;
     428                CHECK_SYS(setsockopt(sk, IPPROTO_IPV6, IPV6_V6ONLY, &opt, sizeof(opt)));
     429        }
     430        #endif /* IPV6_V6ONLY */
     431       
     432        return 0;
     433}
     434
     435
     436/* Post-binding socket options */
     437static int fd_setsockopt_postbind(int sk, int bound_to_default)
     438{
     439        TRACE_ENTRY( "%d %d", sk, bound_to_default);
     440       
     441        CHECK_PARAMS( (sk > 0) );
     442       
     443        /* Set the ASCONF option */
     444        #ifdef SCTP_AUTO_ASCONF
     445        {
     446                int asconf;
     447               
     448                #ifdef DEBUG_SCTP
     449                socklen_t sz;
     450               
     451                sz = sizeof(asconf);
     452                /* Read socket defaults */
     453                CHECK_SYS(  getsockopt(sk, IPPROTO_SCTP, SCTP_AUTO_ASCONF, &asconf, &sz)  );
     454                if (sz != sizeof(asconf))
     455                {
     456                        TRACE_DEBUG(INFO, "Invalid size of socket option: %d / %d", sz, (socklen_t)sizeof(asconf));
     457                        return ENOTSUP;
     458                }
     459                TRACE_DEBUG(FULL, "Def SCTP_AUTO_ASCONF value : %s", asconf ? "true" : "false");
     460                #endif /* DEBUG_SCTP */
     461
     462                asconf = bound_to_default ? 1 : 0;      /* allow automatic use of added or removed addresses in the association (for bound-all sockets) */
     463               
     464                /* Set the option to the socket */
     465                CHECK_SYS(  setsockopt(sk, IPPROTO_SCTP, SCTP_AUTO_ASCONF, &asconf, sizeof(asconf))  );
     466               
     467                #ifdef DEBUG_SCTP
     468                /* Check new values */
     469                CHECK_SYS(  getsockopt(sk, IPPROTO_SCTP, SCTP_AUTO_ASCONF, &asconf, &sz)  );
     470                TRACE_DEBUG(FULL, "New SCTP_AUTO_ASCONF value : %s", asconf ? "true" : "false");
     471                #endif /* DEBUG_SCTP */
     472        }
     473        #else /* SCTP_AUTO_ASCONF */
     474        # ifdef DEBUG_SCTP
     475        TRACE_DEBUG(FULL, "Skipping SCTP_AUTO_ASCONF");
     476        # endif /* DEBUG_SCTP */
     477        #endif /* SCTP_AUTO_ASCONF */
     478       
     479        return 0;
     480}
    37481
    38482/* Create a socket server and bind it according to daemon s configuration */
    39483int fd_sctp_create_bind_server( int * sock, struct fd_list * list, uint16_t port )
    40484{
    41         TODO("Create sctp server, using fd_g_config: cnf_endpoints, no_ip4, no_ip6, cnf_sctp_str");
    42        
    43         return ENOTSUP;
     485        int family;
     486        int bind_default;
     487       
     488        TRACE_ENTRY("%p %p %hu", sock, list, port);
     489        CHECK_PARAMS(sock);
     490       
     491        if (fd_g_config->cnf_flags.no_ip6) {
     492                family = AF_INET;
     493        } else {
     494                family = AF_INET6; /* can create socket for both IP and IPv6 */
     495        }
     496       
     497        /* Create the socket */
     498        CHECK_SYS( *sock = socket(family, SOCK_STREAM, IPPROTO_SCTP) );
     499       
     500        /* Set pre-binding socket options, including number of streams etc... */
     501        CHECK_FCT( fd_setsockopt_prebind(*sock) );
     502       
     503        bind_default = (! list) || (FD_IS_LIST_EMPTY(list)) ;
     504redo:
     505        if ( bind_default ) {
     506                /* Implicit endpoints : bind to default addresses */
     507                union {
     508                        sSS  ss;
     509                        sSA  sa;
     510                        sSA4 sin;
     511                        sSA6 sin6;
     512                } s;
     513               
     514                /* 0.0.0.0 and [::] are all zeros */
     515                memset(&s, 0, sizeof(s));
     516               
     517                s.sa.sa_family = family;
     518               
     519                if (family == AF_INET)
     520                        s.sin.sin_port = htons(port);
     521                else
     522                        s.sin6.sin6_port = htons(port);
     523               
     524                CHECK_SYS( bind(*sock, &s.sa, sizeof(s)) );
     525               
     526        } else {
     527                /* Explicit endpoints to bind to from config */
     528                union {
     529                        sSA     *sa;
     530                        sSA4    *sin;
     531                        sSA6    *sin6;
     532                } sar; /* build the list of endpoints to bind to */
     533                int count = 0; /* number of sock addr in sar array */
     534                struct fd_list * li;
     535               
     536                sar.sa = NULL;
     537               
     538                /* Create a flat array from the list of configured addresses */
     539                for (li = list->next; li != list; li = li->next) {
     540                        struct fd_endpoint * ep = (struct fd_endpoint *)li;
     541                       
     542                        if ( ! ep->meta.conf )
     543                                continue;
     544                       
     545                        count++;
     546                        if (fd_g_config->cnf_flags.no_ip6) {
     547                                ASSERT(ep->sa.sa_family == AF_INET);
     548                                CHECK_MALLOC( sar.sa = realloc(sar.sa, count * sizeof(sSA4))  );
     549                                memcpy(&sar.sin[count - 1], &ep->sin, sizeof(sSA4));
     550                                sar.sin[count - 1].sin_port = htons(port);
     551                        } else {
     552                                /* Pass all addresses as IPv6, eventually mapped -- we already filtered out IPv4 addresses if no_ip4 flag is set */
     553                                CHECK_MALLOC( sar.sa = realloc(sar.sa, count * sizeof(sSA6))  );
     554                                if (ep->sa.sa_family == AF_INET) {
     555                                        memset(&sar.sin6[count - 1], 0, sizeof(sSA6));
     556                                        sar.sin6[count - 1].sin6_family = AF_INET6;
     557                                        IN6_ADDR_V4MAP( &sar.sin6[count - 1].sin6_addr.s6_addr, ep->sin.sin_addr.s_addr );
     558                                } else {
     559                                        memcpy(&sar.sin6[count - 1], &ep->sin6, sizeof(sSA6));
     560                                }
     561                                sar.sin6[count - 1].sin6_port = htons(port);
     562                        }
     563                }
     564               
     565                if (!count) {
     566                        /* None of the addresses in the list came from configuration, we bind to default */
     567                        bind_default = 1;
     568                        goto redo;
     569                }
     570               
     571                # ifdef DEBUG_SCTP
     572                if (TRACE_BOOL(FULL)) {
     573                        int i;
     574                        fd_log_debug("Calling sctp_bindx with the following array:\n");
     575                        for (i = 0; i < count; i++) {
     576                                fd_log_debug("    - ");
     577                                sSA_DUMP_NODE_SERV( (sar.sa[0].sa_family == AF_INET) ? (sSA *)(&sar.sin[i]) : (sSA *)(&sar.sin6[i]), NI_NUMERICHOST | NI_NUMERICSERV );
     578                                fd_log_debug("\n");
     579                        }
     580                }
     581                #endif /* DEBUG_SCTP */
     582               
     583                CHECK_SYS(  sctp_bindx(*sock, sar.sa, count, SCTP_BINDX_ADD_ADDR)  );
     584               
     585        }
     586       
     587        /* Now, the server is bound, set remaining sockopt */
     588        CHECK_FCT( fd_setsockopt_postbind(*sock, bind_default) );
     589       
     590        #ifdef DEBUG_SCTP
     591        /* Debug: show all local listening addresses */
     592        if (TRACE_BOOL(FULL)) {
     593                sSA *sa, *sar;
     594                int sz;
     595               
     596                CHECK_SYS(  sz = sctp_getladdrs(*sock, 0, &sar)  );
     597               
     598                fd_log_debug("SCTP server bound on :\n");
     599                for (sa = sar; sz-- > 0; sa = (sSA *)(((uint8_t *)sa) + ((sa->sa_family == AF_INET) ? sizeof(sSA4) : sizeof(sSA6)))) {
     600                        fd_log_debug("    - ");
     601                        sSA_DUMP_NODE_SERV( sa, NI_NUMERICHOST | NI_NUMERICSERV );
     602                        fd_log_debug("\n");
     603                }
     604                sctp_freeladdrs(sar);
     605        }
     606        #endif /* DEBUG_SCTP */
     607
     608        return 0;
    44609}
    45610
     
    60625}
    61626
     627/* Get the list of local endpoints of the socket */
     628int fd_sctp_get_local_ep(int sock, struct fd_list * list)
     629{
     630        union {
     631                sSA     *sa;
     632                sSA4    *sin;
     633                sSA6    *sin6;
     634                uint8_t *buf;
     635        } ptr;
     636       
     637        sSA * data;
     638        int count;
     639       
     640        TRACE_ENTRY("%d %p", sock, list);
     641        CHECK_PARAMS(list);
     642       
     643        /* Read the list on the socket */
     644        CHECK_SYS( count = sctp_getladdrs(sock, 0, &data)  );
     645        ptr.sa = data;
     646       
     647        while (count) {
     648                TODO("get the data from ptr");
     649                TODO("Increment ptr to the next sa in data");
     650               
     651                count --;
     652        }
     653       
     654        /* And now, free the list and return */
     655        sctp_freeladdrs(data);
     656       
     657        return ENOTSUP;
     658}
     659
     660/* Get the list of remote endpoints of the socket */
     661int fd_sctp_get_remote_ep(int sock, struct fd_list * list)
     662{
     663        TODO("SCTP: sctp_getpaddrs");
     664               
     665       
     666        return ENOTSUP;
     667}
     668
  • freeDiameter/tcp.c

    r22 r23  
    3737#include <netinet/tcp.h>
    3838#include <netinet/ip6.h>
     39#include <sys/socket.h>
    3940
    4041/* Set the socket options for TCP sockets, before bind is called */
     
    111112        return 0;
    112113}
     114
     115/* Get the local name of a TCP socket -- would be nice if it did not return "0.0.0.0"... */
     116int fd_tcp_get_local_ep(int sock, sSS * ss, socklen_t *sl)
     117{
     118        TRACE_ENTRY("%d %p %p", sock, ss, sl);
     119        CHECK_PARAMS( ss && sl );
     120       
     121        *sl = sizeof(sSS);
     122        CHECK_SYS(getsockname(sock, (sSA *)ss, sl));
     123       
     124        return 0;
     125}
     126
     127/* Get the remote name of a TCP socket */
     128int fd_tcp_get_remote_ep(int sock, sSS * ss, socklen_t *sl)
     129{
     130        TRACE_ENTRY("%d %p %p", sock, ss, sl);
     131        CHECK_PARAMS( ss && sl );
     132       
     133        *sl = sizeof(sSS);
     134        CHECK_SYS(getpeername(sock, (sSA *)ss, sl));
     135       
     136        return 0;
     137}
  • include/freeDiameter/CMakeLists.txt

    r17 r23  
    1010
    1111# Disable SCTP support completly ?
    12 OPTION(DISABLE_SCTP "Disable SCTP support?")
     12OPTION(DISABLE_SCTP "Disable SCTP support?" OFF)
     13IF (NOT DISABLE_SCTP)
     14        OPTION(DEBUG_SCTP "Verbose SCTP (for debug)?" OFF)
     15ENDIF (NOT DISABLE_SCTP)
    1316
    1417# Find TODO items in the code easily ?
  • include/freeDiameter/freeDiameter-host.h.in

    r13 r23  
    4545
    4646#cmakedefine DISABLE_SCTP
     47#cmakedefine DEBUG_SCTP
    4748#cmakedefine ERRORS_ON_TODO
    4849#cmakedefine DEBUG
  • include/freeDiameter/freeDiameter.h

    r22 r23  
    118118struct fd_endpoint {
    119119        struct fd_list  chain;  /* link in cnf_endpoints list */
    120         sSS             ss;     /* the socket information. List is always ordered by ss value (memcmp) */
     120        union {
     121                sSS             ss;     /* the socket information. List is always ordered by ss value (memcmp) */
     122                sSA4            sin;
     123                sSA6            sin6;
     124                sSA             sa;
     125        };
    121126        struct {
    122127                unsigned conf : 1; /* This endpoint is statically configured in a configuration file */
     
    129134        }               meta;   /* Additional information about the endpoint */
    130135};
     136
     137/* Add a new entry in a list of endpoints -- merge if the sockaddr was already there */
     138int fd_ep_add_merge( struct fd_list * list, sSA * sa, socklen_t sl, int conf, int disc, int adv, int ll );
    131139
    132140/* Applications */
  • include/freeDiameter/libfreeDiameter.h

    r22 r23  
    329329                        flag);                                  \
    330330          if (__rc)                                             \
    331                 fd_log_debug((char *)gai_strerror(__rc));       \
     331                fd_log_debug("%s", (char *)gai_strerror(__rc)); \
    332332          else                                                  \
    333                 fd_log_debug(&__addrbuf[0]);                    \
     333                fd_log_debug("%s", &__addrbuf[0]);              \
    334334        } else {                                                \
    335335                fd_log_debug("(NULL / ANY)");                   \
    336336        }                                                       \
    337337}
    338 /* if needed, add sSA_DUMP_SERVICE */
     338/* Same, for a service */
     339#define sSA_DUMP_SERV( sa, flag ) {                             \
     340        sSA * __sa = (sSA *)(sa);                               \
     341        char __servbuf[32];                                     \
     342        if (__sa) {                                             \
     343          int __rc = getnameinfo(__sa,                          \
     344                        sizeof(sSS),                            \
     345                        NULL,                                   \
     346                        0,                                      \
     347                        __servbuf,                              \
     348                        sizeof(__servbuf),                      \
     349                        flag);                                  \
     350          if (__rc)                                             \
     351                fd_log_debug("%s", (char *)gai_strerror(__rc)); \
     352          else                                                  \
     353                fd_log_debug("%s", &__servbuf[0]);              \
     354        } else {                                                \
     355                fd_log_debug("(unknown)");                      \
     356        }                                                       \
     357}
     358/* Combine both */
     359#define sSA_DUMP_NODE_SERV( sa, flag ) {                                \
     360        sSA * __sa = (sSA *)(sa);                                       \
     361        char __addrbuf[INET6_ADDRSTRLEN];                               \
     362        char __servbuf[32];                                             \
     363        if (__sa) {                                                     \
     364          int __rc = getnameinfo(__sa,                                  \
     365                        sizeof(sSS),                                    \
     366                        __addrbuf,                                      \
     367                        sizeof(__addrbuf),                              \
     368                        __servbuf,                                      \
     369                        sizeof(__servbuf),                              \
     370                        flag);                                          \
     371          if (__rc)                                                     \
     372                fd_log_debug("%s", (char *)gai_strerror(__rc));         \
     373          else                                                          \
     374                fd_log_debug("[%s]:%s", &__addrbuf[0],&__servbuf[0]);   \
     375        } else {                                                        \
     376                fd_log_debug("(NULL / ANY)");                           \
     377        }                                                               \
     378}
     379
    339380
    340381/* A l4 protocol name (TCP / SCTP) */
Note: See TracChangeset for help on using the changeset viewer.