Allow more than one local or remote address per socket. This is needed to
support SCTP (and MPTCP in the future). No functional change for existing protocols. MFC after: 3 days
This commit is contained in:
parent
7e80c6b0e2
commit
e6f718c750
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=284353
@ -84,6 +84,11 @@ static int *ports;
|
|||||||
#define SET_PORT(p) do { ports[p / INT_BIT] |= 1 << (p % INT_BIT); } while (0)
|
#define SET_PORT(p) do { ports[p / INT_BIT] |= 1 << (p % INT_BIT); } while (0)
|
||||||
#define CHK_PORT(p) (ports[p / INT_BIT] & (1 << (p % INT_BIT)))
|
#define CHK_PORT(p) (ports[p / INT_BIT] & (1 << (p % INT_BIT)))
|
||||||
|
|
||||||
|
struct addr {
|
||||||
|
struct sockaddr_storage address;
|
||||||
|
struct addr *next;
|
||||||
|
};
|
||||||
|
|
||||||
struct sock {
|
struct sock {
|
||||||
void *socket;
|
void *socket;
|
||||||
void *pcb;
|
void *pcb;
|
||||||
@ -92,8 +97,8 @@ struct sock {
|
|||||||
int family;
|
int family;
|
||||||
int proto;
|
int proto;
|
||||||
const char *protoname;
|
const char *protoname;
|
||||||
struct sockaddr_storage laddr;
|
struct addr *laddr;
|
||||||
struct sockaddr_storage faddr;
|
struct addr *faddr;
|
||||||
struct sock *next;
|
struct sock *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -257,6 +262,7 @@ gather_inet(int proto)
|
|||||||
struct inpcb *inp;
|
struct inpcb *inp;
|
||||||
struct xsocket *so;
|
struct xsocket *so;
|
||||||
struct sock *sock;
|
struct sock *sock;
|
||||||
|
struct addr *laddr, *faddr;
|
||||||
const char *varname, *protoname;
|
const char *varname, *protoname;
|
||||||
size_t len, bufsize;
|
size_t len, bufsize;
|
||||||
void *buf;
|
void *buf;
|
||||||
@ -368,21 +374,29 @@ gather_inet(int proto)
|
|||||||
}
|
}
|
||||||
if ((sock = calloc(1, sizeof *sock)) == NULL)
|
if ((sock = calloc(1, sizeof *sock)) == NULL)
|
||||||
err(1, "malloc()");
|
err(1, "malloc()");
|
||||||
|
if ((laddr = calloc(1, sizeof *laddr)) == NULL)
|
||||||
|
err(1, "malloc()");
|
||||||
|
if ((faddr = calloc(1, sizeof *faddr)) == NULL)
|
||||||
|
err(1, "malloc()");
|
||||||
sock->socket = so->xso_so;
|
sock->socket = so->xso_so;
|
||||||
sock->proto = proto;
|
sock->proto = proto;
|
||||||
if (inp->inp_vflag & INP_IPV4) {
|
if (inp->inp_vflag & INP_IPV4) {
|
||||||
sock->family = AF_INET;
|
sock->family = AF_INET;
|
||||||
sockaddr(&sock->laddr, sock->family,
|
sockaddr(&laddr->address, sock->family,
|
||||||
&inp->inp_laddr, inp->inp_lport);
|
&inp->inp_laddr, inp->inp_lport);
|
||||||
sockaddr(&sock->faddr, sock->family,
|
sockaddr(&faddr->address, sock->family,
|
||||||
&inp->inp_faddr, inp->inp_fport);
|
&inp->inp_faddr, inp->inp_fport);
|
||||||
} else if (inp->inp_vflag & INP_IPV6) {
|
} else if (inp->inp_vflag & INP_IPV6) {
|
||||||
sock->family = AF_INET6;
|
sock->family = AF_INET6;
|
||||||
sockaddr(&sock->laddr, sock->family,
|
sockaddr(&laddr->address, sock->family,
|
||||||
&inp->in6p_laddr, inp->inp_lport);
|
&inp->in6p_laddr, inp->inp_lport);
|
||||||
sockaddr(&sock->faddr, sock->family,
|
sockaddr(&faddr->address, sock->family,
|
||||||
&inp->in6p_faddr, inp->inp_fport);
|
&inp->in6p_faddr, inp->inp_fport);
|
||||||
}
|
}
|
||||||
|
laddr->next = NULL;
|
||||||
|
faddr->next = NULL;
|
||||||
|
sock->laddr = laddr;
|
||||||
|
sock->faddr = faddr;
|
||||||
sock->vflag = inp->inp_vflag;
|
sock->vflag = inp->inp_vflag;
|
||||||
sock->protoname = protoname;
|
sock->protoname = protoname;
|
||||||
hash = (int)((uintptr_t)sock->socket % HASHSIZE);
|
hash = (int)((uintptr_t)sock->socket % HASHSIZE);
|
||||||
@ -399,6 +413,7 @@ gather_unix(int proto)
|
|||||||
struct xunpgen *xug, *exug;
|
struct xunpgen *xug, *exug;
|
||||||
struct xunpcb *xup;
|
struct xunpcb *xup;
|
||||||
struct sock *sock;
|
struct sock *sock;
|
||||||
|
struct addr *laddr, *faddr;
|
||||||
const char *varname, *protoname;
|
const char *varname, *protoname;
|
||||||
size_t len, bufsize;
|
size_t len, bufsize;
|
||||||
void *buf;
|
void *buf;
|
||||||
@ -457,16 +472,24 @@ gather_unix(int proto)
|
|||||||
continue;
|
continue;
|
||||||
if ((sock = calloc(1, sizeof *sock)) == NULL)
|
if ((sock = calloc(1, sizeof *sock)) == NULL)
|
||||||
err(1, "malloc()");
|
err(1, "malloc()");
|
||||||
|
if ((laddr = calloc(1, sizeof *laddr)) == NULL)
|
||||||
|
err(1, "malloc()");
|
||||||
|
if ((faddr = calloc(1, sizeof *faddr)) == NULL)
|
||||||
|
err(1, "malloc()");
|
||||||
sock->socket = xup->xu_socket.xso_so;
|
sock->socket = xup->xu_socket.xso_so;
|
||||||
sock->pcb = xup->xu_unpp;
|
sock->pcb = xup->xu_unpp;
|
||||||
sock->proto = proto;
|
sock->proto = proto;
|
||||||
sock->family = AF_UNIX;
|
sock->family = AF_UNIX;
|
||||||
sock->protoname = protoname;
|
sock->protoname = protoname;
|
||||||
if (xup->xu_unp.unp_addr != NULL)
|
if (xup->xu_unp.unp_addr != NULL)
|
||||||
sock->laddr =
|
laddr->address =
|
||||||
*(struct sockaddr_storage *)(void *)&xup->xu_addr;
|
*(struct sockaddr_storage *)(void *)&xup->xu_addr;
|
||||||
else if (xup->xu_unp.unp_conn != NULL)
|
else if (xup->xu_unp.unp_conn != NULL)
|
||||||
*(void **)&sock->faddr = xup->xu_unp.unp_conn;
|
*(void **)&(faddr->address) = xup->xu_unp.unp_conn;
|
||||||
|
laddr->next = NULL;
|
||||||
|
faddr->next = NULL;
|
||||||
|
sock->laddr = laddr;
|
||||||
|
sock->faddr = faddr;
|
||||||
hash = (int)((uintptr_t)sock->socket % HASHSIZE);
|
hash = (int)((uintptr_t)sock->socket % HASHSIZE);
|
||||||
sock->next = sockhash[hash];
|
sock->next = sockhash[hash];
|
||||||
sockhash[hash] = sock;
|
sockhash[hash] = sock;
|
||||||
@ -575,23 +598,28 @@ static int
|
|||||||
check_ports(struct sock *s)
|
check_ports(struct sock *s)
|
||||||
{
|
{
|
||||||
int port;
|
int port;
|
||||||
|
struct addr *addr;
|
||||||
|
|
||||||
if (ports == NULL)
|
if (ports == NULL)
|
||||||
return (1);
|
return (1);
|
||||||
if ((s->family != AF_INET) && (s->family != AF_INET6))
|
if ((s->family != AF_INET) && (s->family != AF_INET6))
|
||||||
return (1);
|
return (1);
|
||||||
if (s->family == AF_INET)
|
for (addr = s->laddr; addr != NULL; addr = addr->next) {
|
||||||
port = ntohs(((struct sockaddr_in *)(&s->laddr))->sin_port);
|
if (addr->address.ss_family == AF_INET)
|
||||||
else
|
port = ntohs(((struct sockaddr_in *)(&addr->address))->sin_port);
|
||||||
port = ntohs(((struct sockaddr_in6 *)(&s->laddr))->sin6_port);
|
else
|
||||||
if (CHK_PORT(port))
|
port = ntohs(((struct sockaddr_in6 *)(&addr->address))->sin6_port);
|
||||||
return (1);
|
if (CHK_PORT(port))
|
||||||
if (s->family == AF_INET)
|
return (1);
|
||||||
port = ntohs(((struct sockaddr_in *)(&s->faddr))->sin_port);
|
}
|
||||||
else
|
for (addr = s->faddr; addr != NULL; addr = addr->next) {
|
||||||
port = ntohs(((struct sockaddr_in6 *)(&s->faddr))->sin6_port);
|
if (addr->address.ss_family == AF_INET)
|
||||||
if (CHK_PORT(port))
|
port = ntohs(((struct sockaddr_in *)&(addr->address))->sin_port);
|
||||||
return (1);
|
else
|
||||||
|
port = ntohs(((struct sockaddr_in6 *)&(addr->address))->sin6_port);
|
||||||
|
if (CHK_PORT(port))
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -600,6 +628,7 @@ displaysock(struct sock *s, int pos)
|
|||||||
{
|
{
|
||||||
void *p;
|
void *p;
|
||||||
int hash;
|
int hash;
|
||||||
|
struct addr *laddr, *faddr;
|
||||||
|
|
||||||
while (pos < 29)
|
while (pos < 29)
|
||||||
pos += xprintf(" ");
|
pos += xprintf(" ");
|
||||||
@ -608,45 +637,65 @@ displaysock(struct sock *s, int pos)
|
|||||||
pos += xprintf("4 ");
|
pos += xprintf("4 ");
|
||||||
if (s->vflag & INP_IPV6)
|
if (s->vflag & INP_IPV6)
|
||||||
pos += xprintf("6 ");
|
pos += xprintf("6 ");
|
||||||
while (pos < 36)
|
laddr = s->laddr;
|
||||||
pos += xprintf(" ");
|
faddr = s->faddr;
|
||||||
switch (s->family) {
|
while (laddr != NULL || faddr != NULL) {
|
||||||
case AF_INET:
|
while (pos < 36)
|
||||||
case AF_INET6:
|
|
||||||
pos += printaddr(&s->laddr);
|
|
||||||
if (s->family == AF_INET6 && pos >= 58)
|
|
||||||
pos += xprintf(" ");
|
pos += xprintf(" ");
|
||||||
while (pos < 58)
|
switch (s->family) {
|
||||||
pos += xprintf(" ");
|
case AF_INET:
|
||||||
pos += printaddr(&s->faddr);
|
case AF_INET6:
|
||||||
break;
|
if (laddr != NULL) {
|
||||||
case AF_UNIX:
|
pos += printaddr(&laddr->address);
|
||||||
/* server */
|
if (s->family == AF_INET6 && pos >= 58)
|
||||||
if (s->laddr.ss_len > 0) {
|
pos += xprintf(" ");
|
||||||
pos += printaddr(&s->laddr);
|
}
|
||||||
|
while (pos < 58)
|
||||||
|
pos += xprintf(" ");
|
||||||
|
if (faddr != NULL)
|
||||||
|
pos += printaddr(&faddr->address);
|
||||||
break;
|
break;
|
||||||
}
|
case AF_UNIX:
|
||||||
/* client */
|
if ((laddr == NULL) || (faddr == NULL))
|
||||||
p = *(void **)&s->faddr;
|
errx(1, "laddr = %p or faddr = %p is NULL",
|
||||||
if (p == NULL) {
|
(void *)laddr, (void *)faddr);
|
||||||
pos += xprintf("(not connected)");
|
/* server */
|
||||||
break;
|
if (laddr->address.ss_len > 0) {
|
||||||
}
|
pos += printaddr(&laddr->address);
|
||||||
pos += xprintf("-> ");
|
|
||||||
for (hash = 0; hash < HASHSIZE; ++hash) {
|
|
||||||
for (s = sockhash[hash]; s != NULL; s = s->next)
|
|
||||||
if (s->pcb == p)
|
|
||||||
break;
|
|
||||||
if (s != NULL)
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
/* client */
|
||||||
|
p = *(void **)&(faddr->address);
|
||||||
|
if (p == NULL) {
|
||||||
|
pos += xprintf("(not connected)");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pos += xprintf("-> ");
|
||||||
|
for (hash = 0; hash < HASHSIZE; ++hash) {
|
||||||
|
for (s = sockhash[hash]; s != NULL; s = s->next)
|
||||||
|
if (s->pcb == p)
|
||||||
|
break;
|
||||||
|
if (s != NULL)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (s == NULL ||
|
||||||
|
s->laddr == NULL ||
|
||||||
|
s->laddr->address.ss_len == 0)
|
||||||
|
pos += xprintf("??");
|
||||||
|
else
|
||||||
|
pos += printaddr(&s->laddr->address);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
if (laddr != NULL)
|
||||||
|
laddr = laddr->next;
|
||||||
|
if (faddr != NULL)
|
||||||
|
faddr = faddr->next;
|
||||||
|
if ((laddr != NULL) || (faddr != NULL)) {
|
||||||
|
xprintf("\n");
|
||||||
|
pos = 0;
|
||||||
}
|
}
|
||||||
if (s == NULL || s->laddr.ss_len == 0)
|
|
||||||
pos += xprintf("??");
|
|
||||||
else
|
|
||||||
pos += printaddr(&s->laddr);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
abort();
|
|
||||||
}
|
}
|
||||||
xprintf("\n");
|
xprintf("\n");
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user