Mercurial > hg > freeDiameter
diff 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 |
line wrap: on
line diff
--- a/libfdcore/sctp.c Thu Apr 30 15:24:47 2020 +1000 +++ b/libfdcore/sctp.c Fri May 01 18:20:33 2020 +1000 @@ -869,7 +869,7 @@ } /* Create a client socket and connect to remote server */ -int fd_sctp_client( int *sock, int no_ip6, uint16_t port, struct fd_list * list ) +int fd_sctp_client( int *sock, int no_ip6, uint16_t port, struct fd_list * list, struct fd_list * src_list ) { int family; union { @@ -879,11 +879,13 @@ size_t size = 0; int count = 0; int ret; + int bind_default = 1; /* enable ASCONF in postbind */ sar.buf = NULL; - TRACE_ENTRY("%p %i %hu %p", sock, no_ip6, port, list); + TRACE_ENTRY("%p %i %hu %p %p", sock, no_ip6, port, list, src_list); CHECK_PARAMS( sock && list && (!FD_IS_LIST_EMPTY(list)) ); + CHECK_PARAMS( !src_list || (src_list && (!FD_IS_LIST_EMPTY(src_list))) ); if (no_ip6) { family = AF_INET; @@ -899,7 +901,29 @@ /* Set the socket options */ CHECK_FCT_DO( ret = fd_setsockopt_prebind(*sock), goto out ); - + + /* Bind to explicit source addresses if requested */ + if (src_list && !FD_IS_LIST_EMPTY(src_list)) { + sSA * bindsar = NULL; /* array of addresses */ + size_t sz = 0; /* size of the array */ + int sarcount = 0; /* number of sock addr in the array */ + + /* Create the array of configured addresses */ + 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 ); + + if (sarcount) { + LOG_A("Bind to local SCTP endpoints (%d addresses attempted) ", sarcount); + + CHECK_SYS_DO( ret = sctp_bindx(*sock, bindsar, sarcount, SCTP_BINDX_ADD_ADDR), goto out ); + } + + /* Disable ASCONF option in postbind */ + bind_default = 0; + + /* We don't need bindsar anymore */ + free(bindsar); + } + /* Create the array of addresses, add first the configured addresses, then the discovered, then the other ones */ 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 ); 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 ); @@ -944,7 +968,7 @@ free(sar.buf); sar.buf = NULL; /* Set the remaining sockopts */ - CHECK_FCT_DO( ret = fd_setsockopt_postbind(*sock, 1), + CHECK_FCT_DO( ret = fd_setsockopt_postbind(*sock, bind_default), { CHECK_SYS_DO( shutdown(*sock, SHUT_RDWR), /* continue */ ); } );