Mercurial > hg > freeDiameter
comparison libfdcore/sctp.c @ 1540:407e0a889c7e
SCTP ConnectPeer: sctp_bindx() to local endpoints
When connecting to an SCTP peer using sctp_connectx() with local
addresses configured with ListenOn, bind to the ListenOn addresses
using sctp_bindx() so that the SCTP INIT only contains the
configured local addresses, matching what is advertised in the CER,
and disable SCTP_AUTO_ASCONF.
If no local addresses are configured with ListenOn, the previous
behaviour of sctp_connectx() and enable SCTP_AUTO_ASCONF is used.
author | Luke Mewburn <luke@mewburn.net> |
---|---|
date | Fri, 01 May 2020 18:20:33 +1000 |
parents | acbfec3df281 |
children | 3365e95bed57 |
comparison
equal
deleted
inserted
replaced
1539:d25ce064c667 | 1540:407e0a889c7e |
---|---|
867 CHECK_SYS( listen(sock, 5) ); | 867 CHECK_SYS( listen(sock, 5) ); |
868 return 0; | 868 return 0; |
869 } | 869 } |
870 | 870 |
871 /* Create a client socket and connect to remote server */ | 871 /* Create a client socket and connect to remote server */ |
872 int fd_sctp_client( int *sock, int no_ip6, uint16_t port, struct fd_list * list ) | 872 int fd_sctp_client( int *sock, int no_ip6, uint16_t port, struct fd_list * list, struct fd_list * src_list ) |
873 { | 873 { |
874 int family; | 874 int family; |
875 union { | 875 union { |
876 uint8_t *buf; | 876 uint8_t *buf; |
877 sSA *sa; | 877 sSA *sa; |
878 } sar; | 878 } sar; |
879 size_t size = 0; | 879 size_t size = 0; |
880 int count = 0; | 880 int count = 0; |
881 int ret; | 881 int ret; |
882 int bind_default = 1; /* enable ASCONF in postbind */ | |
882 | 883 |
883 sar.buf = NULL; | 884 sar.buf = NULL; |
884 | 885 |
885 TRACE_ENTRY("%p %i %hu %p", sock, no_ip6, port, list); | 886 TRACE_ENTRY("%p %i %hu %p %p", sock, no_ip6, port, list, src_list); |
886 CHECK_PARAMS( sock && list && (!FD_IS_LIST_EMPTY(list)) ); | 887 CHECK_PARAMS( sock && list && (!FD_IS_LIST_EMPTY(list)) ); |
888 CHECK_PARAMS( !src_list || (src_list && (!FD_IS_LIST_EMPTY(src_list))) ); | |
887 | 889 |
888 if (no_ip6) { | 890 if (no_ip6) { |
889 family = AF_INET; | 891 family = AF_INET; |
890 } else { | 892 } else { |
891 family = AF_INET6; | 893 family = AF_INET6; |
897 /* Cleanup if we are cancelled */ | 899 /* Cleanup if we are cancelled */ |
898 pthread_cleanup_push(fd_cleanup_socket, sock); | 900 pthread_cleanup_push(fd_cleanup_socket, sock); |
899 | 901 |
900 /* Set the socket options */ | 902 /* Set the socket options */ |
901 CHECK_FCT_DO( ret = fd_setsockopt_prebind(*sock), goto out ); | 903 CHECK_FCT_DO( ret = fd_setsockopt_prebind(*sock), goto out ); |
902 | 904 |
905 /* Bind to explicit source addresses if requested */ | |
906 if (src_list && !FD_IS_LIST_EMPTY(src_list)) { | |
907 sSA * bindsar = NULL; /* array of addresses */ | |
908 size_t sz = 0; /* size of the array */ | |
909 int sarcount = 0; /* number of sock addr in the array */ | |
910 | |
911 /* Create the array of configured addresses */ | |
912 CHECK_FCT_DO( ret = add_addresses_from_list_mask((void *)&bindsar, &sz, &sarcount, family, 0, src_list, EP_FL_CONF, EP_FL_CONF), goto out ); | |
913 | |
914 if (sarcount) { | |
915 LOG_A("Bind to local SCTP endpoints (%d addresses attempted) ", sarcount); | |
916 | |
917 CHECK_SYS_DO( ret = sctp_bindx(*sock, bindsar, sarcount, SCTP_BINDX_ADD_ADDR), goto out ); | |
918 } | |
919 | |
920 /* Disable ASCONF option in postbind */ | |
921 bind_default = 0; | |
922 | |
923 /* We don't need bindsar anymore */ | |
924 free(bindsar); | |
925 } | |
926 | |
903 /* Create the array of addresses, add first the configured addresses, then the discovered, then the other ones */ | 927 /* Create the array of addresses, add first the configured addresses, then the discovered, then the other ones */ |
904 CHECK_FCT_DO( ret = add_addresses_from_list_mask(&sar.buf, &size, &count, family, htons(port), list, EP_FL_CONF, EP_FL_CONF ), goto out ); | 928 CHECK_FCT_DO( ret = add_addresses_from_list_mask(&sar.buf, &size, &count, family, htons(port), list, EP_FL_CONF, EP_FL_CONF ), goto out ); |
905 CHECK_FCT_DO( ret = add_addresses_from_list_mask(&sar.buf, &size, &count, family, htons(port), list, EP_FL_CONF | EP_FL_DISC, EP_FL_DISC ), goto out ); | 929 CHECK_FCT_DO( ret = add_addresses_from_list_mask(&sar.buf, &size, &count, family, htons(port), list, EP_FL_CONF | EP_FL_DISC, EP_FL_DISC ), goto out ); |
906 CHECK_FCT_DO( ret = add_addresses_from_list_mask(&sar.buf, &size, &count, family, htons(port), list, EP_FL_CONF | EP_FL_DISC, 0 ), goto out ); | 930 CHECK_FCT_DO( ret = add_addresses_from_list_mask(&sar.buf, &size, &count, family, htons(port), list, EP_FL_CONF | EP_FL_DISC, 0 ), goto out ); |
907 | 931 |
942 } | 966 } |
943 | 967 |
944 free(sar.buf); sar.buf = NULL; | 968 free(sar.buf); sar.buf = NULL; |
945 | 969 |
946 /* Set the remaining sockopts */ | 970 /* Set the remaining sockopts */ |
947 CHECK_FCT_DO( ret = fd_setsockopt_postbind(*sock, 1), | 971 CHECK_FCT_DO( ret = fd_setsockopt_postbind(*sock, bind_default), |
948 { | 972 { |
949 CHECK_SYS_DO( shutdown(*sock, SHUT_RDWR), /* continue */ ); | 973 CHECK_SYS_DO( shutdown(*sock, SHUT_RDWR), /* continue */ ); |
950 } ); | 974 } ); |
951 | 975 |
952 out: | 976 out: |