code: plan9front

Download patch

ref: 25a0d57478500aed9669e0492583523665afd49d
parent: d618223086e32bc26d64eb20bfcb3de31536782f
author: Benjamin Riefenstahl <b.riefenstahl@turtle-trading.net>
date: Fri Jun 10 16:39:28 EDT 2022

ape/bsd/bind.c, ape/bsd/listen.c: Set local IP.

Despite what the man pages say, local addresses can actually be set so
do that.

--- a/sys/src/ape/lib/bsd/_sock_ingetaddr.c
+++ b/sys/src/ape/lib/bsd/_sock_ingetaddr.c
@@ -40,6 +40,30 @@
 }
 
 int
+_sock_inisany(int af, void *addr)
+{
+	int alen;
+	void *any;
+	/* an IPv4 address that is auto-initialized to all zeros */
+	static struct in_addr inaddr_any;
+
+	switch(af){
+	case AF_INET:
+		alen = sizeof inaddr_any.s_addr;
+		any = &inaddr_any;
+		break;
+	case AF_INET6:
+		alen = sizeof in6addr_any;
+		any = &in6addr_any;
+		break;
+	default:
+		return 0;
+	}
+
+	return 0 == memcmp(addr, any, alen);
+}
+
+int
 _sock_inaddr(int af, char *ip, char *port, void *a, int *alen)
 {
 	int len;
@@ -96,4 +120,24 @@
 		}
 		close(fd);
 	}
+}
+
+char *
+_sock_inaddr2string(Rock *r, char *dest, int dlen)
+{
+	int af = r->domain;
+	void *addr = _sock_inip(&r->addr);
+	int port = _sock_inport(&r->addr);
+	char *d = dest;
+	char *dend = dest+dlen;
+
+	if(!_sock_inisany(af, addr)){
+		inet_ntop(af, addr, d, dlen-1);
+		d = memchr(d, 0, dlen-1);
+		*(d++) = '!';
+	}
+
+	snprintf(d, dend-d, "%d", port);
+
+	return dest;
 }
--- a/sys/src/ape/lib/bsd/bind.c
+++ b/sys/src/ape/lib/bsd/bind.c
@@ -24,7 +24,7 @@
 int
 bind(int fd, void *a, int alen)
 {
-	int n, len, cfd, port;
+	int n, len, cfd;
 	struct sockaddr *sa;
 	Rock *r;
 	char msg[128];
@@ -55,8 +55,10 @@
 		errno = EBADF;
 		return -1;
 	}
-	port = _sock_inport(&r->addr);
-	snprintf(msg, sizeof msg, "bind %d", port);
+
+	strcpy(msg, "bind ");
+	_sock_inaddr2string(r, msg + 5, sizeof msg - 5);
+
 	n = write(cfd, msg, strlen(msg));
 	if(n < 0){
 		errno = EOPNOTSUPP;	/* Improve error reporting!!! */
@@ -63,9 +65,13 @@
 		close(cfd);
 		return -1;
 	}
+
 	close(cfd);
-	if(port <= 0)
+
+	if(_sock_inport(&r->addr) <= 0)
 		_sock_ingetaddr(r, &r->addr, 0, "local");
 
 	return 0;
 }
+
+
--- a/sys/src/ape/lib/bsd/listen.c
+++ b/sys/src/ape/lib/bsd/listen.c
@@ -145,7 +145,8 @@
 			close(cfd);
 			return -1;
 		}
-		snprintf(msg, sizeof msg, "announce %d", _sock_inport(&r->addr));
+		strcpy(msg, "announce ");
+		_sock_inaddr2string(r, msg + 9, sizeof msg - 9);
 		n = write(cfd, msg, strlen(msg));
 		if(n < 0){
 			errno = EOPNOTSUPP;	/* Improve error reporting!!! */
--- a/sys/src/ape/lib/bsd/priv.h
+++ b/sys/src/ape/lib/bsd/priv.h
@@ -43,5 +43,7 @@
 extern int	_sock_ipattr(char*);
 extern void*	_sock_inip(struct sockaddr*);
 extern int	_sock_inport(struct sockaddr*);
+extern int	_sock_inisany(int af, void *addr);
 extern int	_sock_inaddr(int, char*, char*, void*, int*);
 extern void	_sock_ingetaddr(Rock*, void*, int*, char*);
+extern char*	_sock_inaddr2string(Rock *r, char *dest, int dlen);