Skip to content

Commit ac301ec

Browse files
committed
session server UPDATE allow binding on missing address
Add a cmake option to use IP_FREEBIND/IPV6_FREEBIND options. Use the IP_FREEBIND/IPV6_FREEBIND on the socket to allow the bind even if the address is not ready. Signed-off-by: Jeremie Leska <jeremie.leska@6wind.com>
1 parent 39f341a commit ac301ec

3 files changed

Lines changed: 24 additions & 0 deletions

File tree

CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ option(ENABLE_SSH_TLS "Enable NETCONF over SSH and TLS support (via libssh and O
9494
option(ENABLE_DNSSEC "Enable support for SSHFP retrieval using DNSSEC for SSH (requires OpenSSL and libval)" OFF)
9595
option(ENABLE_PAM "Detect and use PAM" ON)
9696
option(ENABLE_COMMON_TARGETS "Define common custom target names such as 'doc' or 'uninstall', may cause conflicts when using add_subdirectory() to build this project" ON)
97+
option(ENABLE_IP_FREEBIND "Enable the IP_FREEBIND/IPV6_FREEBIND options on the listening TCP socket" OFF)
9798
option(BUILD_SHARED_LIBS "By default, shared libs are enabled. Turn off for a static build." ON)
9899
set(READ_INACTIVE_TIMEOUT 20 CACHE STRING "Maximum number of seconds waiting for new data once some data have arrived")
99100
set(READ_ACTIVE_TIMEOUT 300 CACHE STRING "Maximum number of seconds for receiving a full message")
@@ -128,6 +129,10 @@ if(ENABLE_SSH_TLS)
128129
set(SSH_TLS_MACRO "#ifndef NC_ENABLED_SSH_TLS\n#define NC_ENABLED_SSH_TLS\n#endif")
129130
endif()
130131

132+
if(ENABLE_IP_FREEBIND)
133+
set(IP_FREEBIND_MACRO "#ifndef NC_ENABLED_IP_FREEBIND\n#define NC_ENABLED_IP_FREEBIND\n#endif")
134+
endif()
135+
131136
set(headers
132137
src/log.h
133138
src/netconf.h

src/config.h.in

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,4 +83,6 @@
8383
/* Portability feature-check macros. */
8484
#cmakedefine HAVE_PTHREAD_RWLOCKATTR_SETKIND_NP
8585

86+
@IP_FREEBIND_MACRO@
87+
8688
#endif /* NC_CONFIG_H_ */

src/session_server.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,9 @@ nc_sock_bind_inet(int sock, const char *address, uint16_t port, int is_ipv4)
288288
struct sockaddr_storage saddr;
289289
struct sockaddr_in *saddr4;
290290
struct sockaddr_in6 *saddr6;
291+
#ifdef NC_ENABLED_IP_FREEBIND
292+
int opt = 1;
293+
#endif
291294

292295
memset(&saddr, 0, sizeof(struct sockaddr_storage));
293296

@@ -307,6 +310,13 @@ nc_sock_bind_inet(int sock, const char *address, uint16_t port, int is_ipv4)
307310
return -1;
308311
}
309312

313+
#ifdef NC_ENABLED_IP_FREEBIND
314+
if (setsockopt(sock, IPPROTO_IP, IP_FREEBIND, &opt, sizeof(opt))) {
315+
ERR(NULL, "Could not add IP_FREEBIND option (%s).", strerror(errno));
316+
return -1;
317+
}
318+
#endif
319+
310320
if (bind(sock, (struct sockaddr *)saddr4, sizeof(struct sockaddr_in)) == -1) {
311321
ERR(NULL, "Could not bind %s:%" PRIu16 " (%s).", address, port, strerror(errno));
312322
return -1;
@@ -328,6 +338,13 @@ nc_sock_bind_inet(int sock, const char *address, uint16_t port, int is_ipv4)
328338
return -1;
329339
}
330340

341+
#ifdef NC_ENABLED_IP_FREEBIND
342+
if (setsockopt(sock, IPPROTO_IPV6, IPV6_FREEBIND, &opt, sizeof(opt))) {
343+
ERR(NULL, "Could not add IPV6_FREEBIND option (%s).", strerror(errno));
344+
return -1;
345+
}
346+
#endif
347+
331348
if (bind(sock, (struct sockaddr *)saddr6, sizeof(struct sockaddr_in6)) == -1) {
332349
ERR(NULL, "Could not bind [%s]:%" PRIu16 " (%s).", address, port, strerror(errno));
333350
return -1;

0 commit comments

Comments
 (0)