Navigation


Changeset 24:bd83ce9328ed in freeDiameter for freeDiameter/sctp.c


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

Cleanups and completed sctp code (not finished)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • freeDiameter/sctp.c

    r23 r24  
    7676                }
    7777               
    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);
     78                TRACE_DEBUG(FULL, "SCTP_EVENTS : sctp_data_io_event          : %hhu", event.sctp_data_io_event);
     79                TRACE_DEBUG(FULL, "              sctp_association_event      : %hhu", event.sctp_association_event);
     80                TRACE_DEBUG(FULL, "              sctp_address_event          : %hhu", event.sctp_address_event);
     81                TRACE_DEBUG(FULL, "              sctp_send_failure_event     : %hhu", event.sctp_send_failure_event);
     82                TRACE_DEBUG(FULL, "              sctp_peer_error_event       : %hhu", event.sctp_peer_error_event);
     83                TRACE_DEBUG(FULL, "              sctp_shutdown_event         : %hhu", event.sctp_shutdown_event);
     84                TRACE_DEBUG(FULL, "              sctp_partial_delivery_event : %hhu", event.sctp_partial_delivery_event);
     85                TRACE_DEBUG(FULL, "              sctp_adaptation_layer_event : %hhu", event.sctp_adaptation_layer_event);
     86                // TRACE_DEBUG(FULL, "             sctp_authentication_event    : %hhu", event.sctp_authentication_event);
    8787                #endif /* DEBUG_SCTP */
    8888               
     
    104104                        return ENOTSUP;
    105105                }
    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);
     106                TRACE_DEBUG(FULL, "Def SCTP_INITMSG : sinit_num_ostreams   : %hu", init.sinit_num_ostreams);
     107                TRACE_DEBUG(FULL, "                  sinit_max_instreams  : %hu", init.sinit_max_instreams);
     108                TRACE_DEBUG(FULL, "                  sinit_max_attempts   : %hu", init.sinit_max_attempts);
     109                TRACE_DEBUG(FULL, "                  sinit_max_init_timeo : %hu", init.sinit_max_init_timeo);
    110110                #endif /* DEBUG_SCTP */
    111111
     
    120120                /* Check new values */
    121121                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);
     122                TRACE_DEBUG(FULL, "New SCTP_INITMSG : sinit_num_ostreams   : %hu", init.sinit_num_ostreams);
     123                TRACE_DEBUG(FULL, "                  sinit_max_instreams  : %hu", init.sinit_max_instreams);
     124                TRACE_DEBUG(FULL, "                  sinit_max_attempts   : %hu", init.sinit_max_attempts);
     125                TRACE_DEBUG(FULL, "                  sinit_max_init_timeo : %hu", init.sinit_max_init_timeo);
    126126                #endif /* DEBUG_SCTP */
    127127        }
     
    175175                        return ENOTSUP;
    176176                }
    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);
     177                TRACE_DEBUG(FULL, "Def SCTP_RTOINFO : srto_initial : %u", rtoinfo.srto_initial);
     178                TRACE_DEBUG(FULL, "                  srto_max     : %u", rtoinfo.srto_max);
     179                TRACE_DEBUG(FULL, "                  srto_min     : %u", rtoinfo.srto_min);
    180180                #endif /* DEBUG_SCTP */
    181181
     
    188188                /* Check new values */
    189189                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);
     190                TRACE_DEBUG(FULL, "New SCTP_RTOINFO : srto_initial : %u", rtoinfo.srto_initial);
     191                TRACE_DEBUG(FULL, "                  srto_max     : %u", rtoinfo.srto_max);
     192                TRACE_DEBUG(FULL, "                  srto_min     : %u", rtoinfo.srto_min);
    193193                #endif /* DEBUG_SCTP */
    194194        }
     
    214214                        return ENOTSUP;
    215215                }
    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);
     216                TRACE_DEBUG(FULL, "Def SCTP_ASSOCINFO : sasoc_asocmaxrxt               : %hu", assoc.sasoc_asocmaxrxt);
     217                TRACE_DEBUG(FULL, "                    sasoc_number_peer_destinations : %hu", assoc.sasoc_number_peer_destinations);
     218                TRACE_DEBUG(FULL, "                    sasoc_peer_rwnd                : %u" , assoc.sasoc_peer_rwnd);
     219                TRACE_DEBUG(FULL, "                    sasoc_local_rwnd               : %u" , assoc.sasoc_local_rwnd);
     220                TRACE_DEBUG(FULL, "                    sasoc_cookie_life              : %u" , assoc.sasoc_cookie_life);
    221221                #endif /* DEBUG_SCTP */
    222222
     
    229229                /* Check new values */
    230230                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);
     231                TRACE_DEBUG(FULL, "New SCTP_ASSOCINFO : sasoc_asocmaxrxt               : %hu", assoc.sasoc_asocmaxrxt);
     232                TRACE_DEBUG(FULL, "                    sasoc_number_peer_destinations : %hu", assoc.sasoc_number_peer_destinations);
     233                TRACE_DEBUG(FULL, "                    sasoc_peer_rwnd                : %u" , assoc.sasoc_peer_rwnd);
     234                TRACE_DEBUG(FULL, "                    sasoc_local_rwnd               : %u" , assoc.sasoc_local_rwnd);
     235                TRACE_DEBUG(FULL, "                    sasoc_cookie_life              : %u" , assoc.sasoc_cookie_life);
    236236                #endif /* DEBUG_SCTP */
    237237        }
     
    258258                        return ENOTSUP;
    259259                }
    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);
     260                TRACE_DEBUG(FULL, "Def SO_LINGER : l_onoff  : %d", linger.l_onoff);
     261                TRACE_DEBUG(FULL, "                l_linger : %d", linger.l_linger);
    262262                #endif /* DEBUG_SCTP */
    263263               
     
    271271                /* Check new values */
    272272                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);
     273                TRACE_DEBUG(FULL, "New SO_LINGER : l_onoff  : %d", linger.l_onoff);
     274                TRACE_DEBUG(FULL, "                l_linger : %d", linger.l_linger);
    275275                #endif /* DEBUG_SCTP */
    276276        }
     
    370370                #endif /* DEBUG_SCTP */
    371371
     372#ifndef SCTP_USE_MAPPED_ADDRESSES
    372373                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#else /* SCTP_USE_MAPPED_ADDRESSES */
     375                v4mapped = 1;   /* but we may have to, otherwise the bind fails in some environments */
     376#endif /* SCTP_USE_MAPPED_ADDRESSES */
    374377               
    375378                /* Set the option to the socket */
     
    422425        */
    423426       
    424         /* In case of no_ip4, force the v6only option */
     427        /* In case of no_ip4, force the v6only option -- is it a valid option for SCTP ? */
    425428        #ifdef IPV6_V6ONLY
    426429        if (fd_g_config->cnf_flags.no_ip4) {
     
    526529        } else {
    527530                /* Explicit endpoints to bind to from config */
     531               
    528532                union {
    529                         sSA     *sa;
    530                         sSA4    *sin;
    531                         sSA6    *sin6;
    532                 } sar; /* build the list of endpoints to bind to */
     533                        sSA     * sa;
     534                        sSA4    *sin;
     535                        sSA6    *sin6;
     536                        uint8_t *buf;
     537                } ptr;
     538                union {
     539                        sSA     * sa;
     540                        uint8_t * buf;
     541                } sar;
    533542                int count = 0; /* number of sock addr in sar array */
     543                size_t offset = 0;
    534544                struct fd_list * li;
    535545               
    536                 sar.sa = NULL;
     546                sar.buf = NULL;
    537547               
    538548                /* Create a flat array from the list of configured addresses */
    539549                for (li = list->next; li != list; li = li->next) {
    540550                        struct fd_endpoint * ep = (struct fd_endpoint *)li;
     551                        size_t sz = 0;
    541552                       
    542                         if ( ! ep->meta.conf )
     553                        if (! (ep->flags & EP_FL_CONF))
    543554                                continue;
    544555                       
    545556                        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);
     557                       
     558                        /* Size of the new SA we are adding (sar may contain a mix of sockaddr_in and sockaddr_in6) */
     559#ifndef SCTP_USE_MAPPED_ADDRESSES
     560                        if (ep->sa.sa_family == AF_INET6)
     561#else /* SCTP_USE_MAPPED_ADDRESSES */
     562                        if (family == AF_INET6)
     563#endif /* SCTP_USE_MAPPED_ADDRESSES */
     564                                sz = sizeof(sSA6);
     565                        else
     566                                sz = sizeof(sSA4);
     567                       
     568                        /* augment sar to contain the additional info */
     569                        CHECK_MALLOC( sar.buf = realloc(sar.buf, offset + sz)  );
     570                       
     571                        ptr.buf = sar.buf + offset; /* place of the new SA */
     572                        offset += sz; /* update to end of sar */
     573                       
     574                        if (sz == sizeof(sSA4)) {
     575                                memcpy(ptr.buf, &ep->sin, sz);
     576                                ptr.sin->sin_port = htons(port);
    551577                        } 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 );
     578                                if (ep->sa.sa_family == AF_INET) { /* We must map the address */
     579                                        memset(ptr.buf, 0, sz);
     580                                        ptr.sin6->sin6_family = AF_INET6;
     581                                        IN6_ADDR_V4MAP( &ptr.sin6->sin6_addr.s6_addr, ep->sin.sin_addr.s_addr );
    558582                                } else {
    559                                         memcpy(&sar.sin6[count - 1], &ep->sin6, sizeof(sSA6));
     583                                        memcpy(ptr.sin6, &ep->sin6, sz);
    560584                                }
    561                                 sar.sin6[count - 1].sin6_port = htons(port);
     585                                ptr.sin6->sin6_port = htons(port);
    562586                        }
    563587                }
     
    572596                if (TRACE_BOOL(FULL)) {
    573597                        int i;
    574                         fd_log_debug("Calling sctp_bindx with the following array:\n");
     598                        ptr.buf = sar.buf;
     599                        fd_log_debug("Calling sctp_bindx with the following address array:\n");
    575600                        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");
     601                                TRACE_DEBUG_sSA(FULL, "    - ", ptr.sa, NI_NUMERICHOST | NI_NUMERICSERV, "" );
     602                                ptr.buf += (ptr.sa->sa_family == AF_INET) ? sizeof(sSA4) : sizeof(sSA6) ;
    579603                        }
    580604                }
    581605                #endif /* DEBUG_SCTP */
    582606               
     607                /* Bind to this array */
    583608                CHECK_SYS(  sctp_bindx(*sock, sar.sa, count, SCTP_BINDX_ADD_ADDR)  );
    584609               
     610                /* We don't need sar anymore */
     611                free(sar.buf);
    585612        }
    586613       
     
    591618        /* Debug: show all local listening addresses */
    592619        if (TRACE_BOOL(FULL)) {
    593                 sSA *sa, *sar;
     620                sSA *sar;
     621                union {
     622                        sSA     *sa;
     623                        uint8_t *buf;
     624                } ptr;
    594625                int sz;
    595626               
     
    597628               
    598629                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");
     630                for (ptr.sa = sar; sz-- > 0; ptr.buf += (ptr.sa->sa_family == AF_INET) ? sizeof(sSA4) : sizeof(sSA6)) {
     631                        TRACE_DEBUG_sSA(FULL, "    - ", ptr.sa, NI_NUMERICHOST | NI_NUMERICSERV, "" );
    603632                }
    604633                sctp_freeladdrs(sar);
     
    617646}
    618647
    619 /* Retrieve streams information from a connected association */
    620 int fd_sctp_get_str_info( int socket, int *in, int *out )
     648/* Create a client socket and connect to remote server */
     649int fd_sctp_client( int *sock, int no_ip6, uint16_t port, struct fd_list * list )
    621650{
    622         TODO("Retrieve streams info from the socket");
    623        
    624         return ENOTSUP;
     651        int family;
     652        int count = 0;
     653        size_t offset = 0, sz;
     654        union {
     655                uint8_t *buf;
     656                sSA     *sa;
     657        } sar;
     658        union {
     659                uint8_t *buf;
     660                sSA     *sa;
     661                sSA4    *sin;
     662                sSA6    *sin6;
     663        } ptr;
     664        struct fd_list * li;
     665        int ret;
     666       
     667        sar.buf = NULL;
     668       
     669        TRACE_ENTRY("%p %i %hu %p", sock, no_ip6, port, list);
     670        CHECK_PARAMS( sock && list && (!FD_IS_LIST_EMPTY(list)) );
     671       
     672        if (no_ip6) {
     673                family = AF_INET;
     674        } else {
     675                family = AF_INET6;
     676        }
     677       
     678        /* Create the socket */
     679        CHECK_SYS( *sock = socket(family, SOCK_STREAM, IPPROTO_SCTP) );
     680       
     681        /* Cleanup if we are cancelled */
     682        pthread_cleanup_push(fd_cleanup_socket, sock);
     683       
     684        /* Set the socket options */
     685        CHECK_FCT_DO( ret = fd_setsockopt_prebind(*sock), goto fail );
     686       
     687        /* Create the array of addresses for sctp_connectx */
     688        for (li = list->next; li != list; li = li->next) {
     689                struct fd_endpoint * ep = (struct fd_endpoint *) li;
     690               
     691                count++;
     692               
     693                /* Size of the new SA we are adding (sar may contain a mix of sockaddr_in and sockaddr_in6) */
     694#ifndef SCTP_USE_MAPPED_ADDRESSES
     695                if (ep->sa.sa_family == AF_INET6)
     696#else /* SCTP_USE_MAPPED_ADDRESSES */
     697                if (family == AF_INET6)
     698#endif /* SCTP_USE_MAPPED_ADDRESSES */
     699                        sz = sizeof(sSA6);
     700                else
     701                        sz = sizeof(sSA4);
     702               
     703                /* augment sar to contain the additional info */
     704                CHECK_MALLOC_DO( sar.buf = realloc(sar.buf, offset + sz), { ret = ENOMEM; goto fail; }  );
     705
     706                ptr.buf = sar.buf + offset; /* place of the new SA */
     707                offset += sz; /* update to end of sar */
     708                       
     709                if (sz == sizeof(sSA4)) {
     710                        memcpy(ptr.buf, &ep->sin, sz);
     711                        ptr.sin->sin_port = htons(port);
     712                } else {
     713                        if (ep->sa.sa_family == AF_INET) { /* We must map the address */
     714                                memset(ptr.buf, 0, sz);
     715                                ptr.sin6->sin6_family = AF_INET6;
     716                                IN6_ADDR_V4MAP( &ptr.sin6->sin6_addr.s6_addr, ep->sin.sin_addr.s_addr );
     717                        } else {
     718                                memcpy(ptr.sin6, &ep->sin6, sz);
     719                        }
     720                        ptr.sin6->sin6_port = htons(port);
     721                }
     722        }
     723       
     724        /* Try connecting */
     725        TRACE_DEBUG(FULL, "Attempting SCTP connection (%d addresses attempted)...", count);
     726        CHECK_SYS_DO( sctp_connectx(*sock, sar.sa, count), { ret = errno; goto fail; } );
     727        free(sar.buf); sar.buf = NULL;
     728       
     729        /* Set the remaining sockopts */
     730        CHECK_FCT_DO( ret = fd_setsockopt_postbind(*sock, 1), goto fail );
     731       
     732        /* Done! */
     733        pthread_cleanup_pop(0);
     734        return 0;
     735       
     736fail:
     737        if (*sock > 0) {
     738                shutdown(*sock, SHUT_RDWR);
     739                *sock = -1;
     740        }
     741        free(sar.buf);
     742        return ret;
     743}
     744
     745/* Retrieve streams information from a connected association -- optionaly provide the primary address */
     746int fd_sctp_get_str_info( int sock, int *in, int *out, sSS *primary )
     747{
     748        struct sctp_status status;
     749        socklen_t sz = sizeof(status);
     750       
     751        TRACE_ENTRY("%d %p %p %p", sock, in, out, primary);
     752        CHECK_PARAMS( (sock > 0) && in && out );
     753       
     754        /* Read the association parameters */
     755        memset(&status, 0, sizeof(status));
     756        CHECK_SYS(  getsockopt(sock, IPPROTO_SCTP, SCTP_STATUS, &status, &sz) );
     757        if (sz != sizeof(status))
     758        {
     759                TRACE_DEBUG(INFO, "Invalid size of socket option: %d / %g", sz, sizeof(status));
     760                return ENOTSUP;
     761        }
     762        #ifdef DEBUG_SCTP
     763        TRACE_DEBUG(FULL, "SCTP_STATUS : sstat_state                  : %i" , status.sstat_state);
     764        TRACE_DEBUG(FULL, "              sstat_rwnd                   : %u" , status.sstat_rwnd);
     765        TRACE_DEBUG(FULL, "              sstat_unackdata              : %hu", status.sstat_unackdata);
     766        TRACE_DEBUG(FULL, "              sstat_penddata               : %hu", status.sstat_penddata);
     767        TRACE_DEBUG(FULL, "              sstat_instrms                : %hu", status.sstat_instrms);
     768        TRACE_DEBUG(FULL, "              sstat_outstrms               : %hu", status.sstat_outstrms);
     769        TRACE_DEBUG(FULL, "              sstat_fragmentation_point    : %u" , status.sstat_fragmentation_point);
     770        TRACE_DEBUG_sSA(FULL, "          sstat_primary.spinfo_address : ", &status.sstat_primary.spinfo_address, NI_NUMERICHOST | NI_NUMERICSERV, "" );
     771        TRACE_DEBUG(FULL, "              sstat_primary.spinfo_state   : %d" , status.sstat_primary.spinfo_state);
     772        TRACE_DEBUG(FULL, "              sstat_primary.spinfo_cwnd    : %u" , status.sstat_primary.spinfo_cwnd);
     773        TRACE_DEBUG(FULL, "              sstat_primary.spinfo_srtt    : %u" , status.sstat_primary.spinfo_srtt);
     774        TRACE_DEBUG(FULL, "              sstat_primary.spinfo_rto     : %u" , status.sstat_primary.spinfo_rto);
     775        TRACE_DEBUG(FULL, "              sstat_primary.spinfo_mtu     : %u" , status.sstat_primary.spinfo_mtu);
     776        #endif /* DEBUG_SCTP */
     777       
     778        *in = (int)status.sstat_instrms;
     779        *out = (int)status.sstat_outstrms;
     780       
     781        if (primary)
     782                memcpy(primary, &status.sstat_primary.spinfo_address, sizeof(sSS));
     783       
     784        return 0;
    625785}
    626786
     
    630790        union {
    631791                sSA     *sa;
    632                 sSA4    *sin;
    633                 sSA6    *sin6;
    634792                uint8_t *buf;
    635793        } ptr;
     
    646804       
    647805        while (count) {
    648                 TODO("get the data from ptr");
    649                 TODO("Increment ptr to the next sa in data");
    650                
     806                socklen_t sl;
     807                switch (ptr.sa->sa_family) {
     808                        case AF_INET:   sl = sizeof(sSA4); break;
     809                        case AF_INET6:  sl = sizeof(sSA6); break;
     810                        default:
     811                                TRACE_DEBUG(INFO, "Unkown address family returned in sctp_getladdrs: %d", ptr.sa->sa_family);
     812                }
     813                               
     814                CHECK_FCT( fd_ep_add_merge( list, ptr.sa, sl, EP_FL_LL ) );
     815                ptr.buf += sl;
    651816                count --;
    652817        }
    653818       
    654         /* And now, free the list and return */
     819        /* Free the list */
    655820        sctp_freeladdrs(data);
    656821       
    657         return ENOTSUP;
     822        /* Now get the primary address, the add function will take care of merging with existing entry */
     823        {
     824                 
     825                struct sctp_status status;
     826                socklen_t sz = sizeof(status);
     827                int ret;
     828               
     829                memset(&status, 0, sizeof(status));
     830                /* Attempt to use SCTP_STATUS message to retrieve the primary address */
     831                ret = getsockopt(sock, IPPROTO_SCTP, SCTP_STATUS, &status, &sz);
     832                if (sz != sizeof(status))
     833                        ret = -1;
     834                sz = sizeof(sSS);
     835                if (ret < 0)
     836                {
     837                        /* Fallback to getsockname -- not recommended by draft-ietf-tsvwg-sctpsocket-19#section-7.4 */
     838                        CHECK_SYS(getsockname(sock, (sSA *)&status.sstat_primary.spinfo_address, &sz));
     839                }
     840                       
     841                CHECK_FCT( fd_ep_add_merge( list, (sSA *)&status.sstat_primary.spinfo_address, sz, EP_FL_PRIMARY ) );
     842        }
     843       
     844        return 0;
    658845}
    659846
     
    661848int fd_sctp_get_remote_ep(int sock, struct fd_list * list)
    662849{
    663         TODO("SCTP: sctp_getpaddrs");
    664                
    665        
    666         return ENOTSUP;
     850        union {
     851                sSA     *sa;
     852                uint8_t *buf;
     853        } ptr;
     854       
     855        sSA * data;
     856        int count;
     857       
     858        TRACE_ENTRY("%d %p", sock, list);
     859        CHECK_PARAMS(list);
     860       
     861        /* Read the list on the socket */
     862        CHECK_SYS( count = sctp_getpaddrs(sock, 0, &data)  );
     863        ptr.sa = data;
     864       
     865        while (count) {
     866                socklen_t sl;
     867                switch (ptr.sa->sa_family) {
     868                        case AF_INET:   sl = sizeof(sSA4); break;
     869                        case AF_INET6:  sl = sizeof(sSA6); break;
     870                        default:
     871                                TRACE_DEBUG(INFO, "Unkown address family returned in sctp_getpaddrs: %d", ptr.sa->sa_family);
     872                }
     873                               
     874                CHECK_FCT( fd_ep_add_merge( list, ptr.sa, sl, EP_FL_LL ) );
     875                ptr.buf += sl;
     876                count --;
     877        }
     878       
     879        /* Free the list */
     880        sctp_freepaddrs(data);
     881       
     882        /* Now get the primary address, the add function will take care of merging with existing entry */
     883        {
     884                sSS ss;
     885                socklen_t sl = sizeof(sSS);
     886       
     887                CHECK_SYS(getpeername(sock, (sSA *)&ss, &sl));
     888                CHECK_FCT( fd_ep_add_merge( list, (sSA *)&ss, sl, EP_FL_PRIMARY ) );
     889        }
     890       
     891        /* Done! */
     892        return 0;
    667893}
    668894
Note: See TracChangeset for help on using the changeset viewer.