librb: commio: Must set addrlen before every call to accept()

If an IPv4 connection is dropped by the pre-callback, and there is a
pending IPv6 connection on the same listening socket then the retried
accept() will be unable to populate `st` because `addrlen` will be too
small. Also initialise `st` each time to avoid a clang static analysis
warning.
This commit is contained in:
Simon Arlott 2017-07-29 21:38:34 +01:00
parent 8467fd9caf
commit b0adc7bf97
No known key found for this signature in database
GPG key ID: C8975F2043CA5D24

View file

@ -346,11 +346,14 @@ rb_accept_tryaccept(rb_fde_t *F, void *data)
{ {
struct rb_sockaddr_storage st; struct rb_sockaddr_storage st;
rb_fde_t *new_F; rb_fde_t *new_F;
rb_socklen_t addrlen = sizeof(st); rb_socklen_t addrlen;
int new_fd; int new_fd;
while(1) while(1)
{ {
memset(&st, 0, sizeof(st));
addrlen = sizeof(st);
new_fd = accept(F->fd, (struct sockaddr *)&st, &addrlen); new_fd = accept(F->fd, (struct sockaddr *)&st, &addrlen);
rb_get_errno(); rb_get_errno();
if(new_fd < 0) if(new_fd < 0)
@ -752,9 +755,6 @@ mangle_mapped_sockaddr(struct sockaddr *in)
{ {
struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)in; struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)in;
if(in->sa_family == AF_INET)
return;
if(in->sa_family == AF_INET6 && IN6_IS_ADDR_V4MAPPED(&in6->sin6_addr)) if(in->sa_family == AF_INET6 && IN6_IS_ADDR_V4MAPPED(&in6->sin6_addr))
{ {
struct sockaddr_in in4; struct sockaddr_in in4;
@ -764,7 +764,6 @@ mangle_mapped_sockaddr(struct sockaddr *in)
in4.sin_addr.s_addr = ((uint32_t *)&in6->sin6_addr)[3]; in4.sin_addr.s_addr = ((uint32_t *)&in6->sin6_addr)[3];
memcpy(in, &in4, sizeof(struct sockaddr_in)); memcpy(in, &in4, sizeof(struct sockaddr_in));
} }
return;
} }
#endif #endif