session UPDATE add call home local binding support
diff --git a/src/session_server.c b/src/session_server.c
index 14bc410..63906ec 100644
--- a/src/session_server.c
+++ b/src/session_server.c
@@ -272,14 +272,65 @@
#endif
int
+nc_sock_bind_inet(int sock, const char *address, uint16_t port, int is_ipv4)
+{
+ struct sockaddr_storage saddr;
+ struct sockaddr_in *saddr4;
+ struct sockaddr_in6 *saddr6;
+
+ memset(&saddr, 0, sizeof(struct sockaddr_storage));
+
+ if (is_ipv4) {
+ saddr4 = (struct sockaddr_in *)&saddr;
+
+ saddr4->sin_family = AF_INET;
+ saddr4->sin_port = htons(port);
+
+ /* determine the address */
+ if (!address) {
+ /* set the implicit default IPv4 address */
+ address = "0.0.0.0";
+ }
+ if (inet_pton(AF_INET, address, &saddr4->sin_addr) != 1) {
+ ERR(NULL, "Failed to convert IPv4 address \"%s\".", address);
+ return -1;
+ }
+
+ if (bind(sock, (struct sockaddr *)saddr4, sizeof(struct sockaddr_in)) == -1) {
+ ERR(NULL, "Could not bind %s:%" PRIu16 " (%s).", address, port, strerror(errno));
+ return -1;
+ }
+
+ } else {
+ saddr6 = (struct sockaddr_in6 *)&saddr;
+
+ saddr6->sin6_family = AF_INET6;
+ saddr6->sin6_port = htons(port);
+
+ /* determine the address */
+ if (!address) {
+ /* set the implicit default IPv6 address */
+ address = "::";
+ }
+ if (inet_pton(AF_INET6, address, &saddr6->sin6_addr) != 1) {
+ ERR(NULL, "Failed to convert IPv6 address \"%s\".", address);
+ return -1;
+ }
+
+ if (bind(sock, (struct sockaddr *)saddr6, sizeof(struct sockaddr_in6)) == -1) {
+ ERR(NULL, "Could not bind [%s]:%" PRIu16 " (%s).", address, port, strerror(errno));
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+int
nc_sock_listen_inet(const char *address, uint16_t port)
{
int opt;
int is_ipv4, sock;
- struct sockaddr_storage saddr;
-
- struct sockaddr_in *saddr4;
- struct sockaddr_in6 *saddr6;
if (!strchr(address, ':')) {
is_ipv4 = 1;
@@ -304,38 +355,9 @@
goto fail;
}
- memset(&saddr, 0, sizeof(struct sockaddr_storage));
- if (is_ipv4) {
- saddr4 = (struct sockaddr_in *)&saddr;
-
- saddr4->sin_family = AF_INET;
- saddr4->sin_port = htons(port);
-
- if (inet_pton(AF_INET, address, &saddr4->sin_addr) != 1) {
- ERR(NULL, "Failed to convert IPv4 address \"%s\".", address);
- goto fail;
- }
-
- if (bind(sock, (struct sockaddr *)saddr4, sizeof(struct sockaddr_in)) == -1) {
- ERR(NULL, "Could not bind \"%s\" port %d (%s).", address, port, strerror(errno));
- goto fail;
- }
-
- } else {
- saddr6 = (struct sockaddr_in6 *)&saddr;
-
- saddr6->sin6_family = AF_INET6;
- saddr6->sin6_port = htons(port);
-
- if (inet_pton(AF_INET6, address, &saddr6->sin6_addr) != 1) {
- ERR(NULL, "Failed to convert IPv6 address \"%s\".", address);
- goto fail;
- }
-
- if (bind(sock, (struct sockaddr *)saddr6, sizeof(struct sockaddr_in6)) == -1) {
- ERR(NULL, "Could not bind \"%s\" port %d (%s).", address, port, strerror(errno));
- goto fail;
- }
+ /* bind the socket */
+ if (nc_sock_bind_inet(sock, address, port, is_ipv4)) {
+ goto fail;
}
if (listen(sock, NC_REVERSE_QUEUE) == -1) {
@@ -2491,7 +2513,8 @@
struct timespec ts_cur;
char *ip_host;
- sock = nc_sock_connect(endpt->address, endpt->port, NC_CH_CONNECT_TIMEOUT, &endpt->ka, &endpt->sock_pending, &ip_host);
+ sock = nc_sock_connect(endpt->src_addr, endpt->src_port, endpt->dst_addr, endpt->dst_port,
+ NC_CH_CONNECT_TIMEOUT, &endpt->ka, &endpt->sock_pending, &ip_host);
if (sock < 0) {
return NC_MSG_ERROR;
}
@@ -2515,7 +2538,7 @@
(*session)->ctx = (struct ly_ctx *)ctx;
(*session)->flags = NC_SESSION_SHAREDCTX | NC_SESSION_CALLHOME;
(*session)->host = ip_host;
- (*session)->port = endpt->port;
+ (*session)->port = endpt->dst_port;
/* sock gets assigned to session or closed */
if (endpt->ti == NC_TI_SSH) {