int sockaddr_from_irc(struct sockaddr_in *v4, const struct irc_sockaddr *irc, int compat_fd, int family)
{
assert(irc != 0);
+ memset(v4, 0, sizeof(*v4));
v4->sin_family = AF_INET;
if (irc) {
assert(!irc->addr.in6_16[0] && !irc->addr.in6_16[1] && !irc->addr.in6_16[2] && !irc->addr.in6_16[3] && !irc->addr.in6_16[4] && (!irc->addr.in6_16[5] || irc->addr.in6_16[5] == 0xffff));
memcpy(&v4->sin_addr, &irc->addr.in6_16[6], sizeof(v4->sin_addr));
v4->sin_port = htons(irc->port);
- } else{
- memset(&v4, 0, sizeof(v4));
}
(void)compat_fd; (void)family;
return sizeof(*v4);
if (0 < (res = recv(fd, buf, length, 0))) {
*count_out = (unsigned) res;
return IO_SUCCESS;
+ } else if (res == 0) {
+ *count_out = 0;
+ errno = 0; /* or ECONNRESET? */
+ return IO_FAILURE;
} else {
*count_out = 0;
- return (res < 0) && is_blocked(errno) ? IO_BLOCKED : IO_FAILURE;
+ return is_blocked(errno) ? IO_BLOCKED : IO_FAILURE;
}
}
}
if (local) {
#if defined(IPV6_V6ONLY)
- int on = 0;
- if (family == 0 && irc_in_addr_unspec(&local->addr))
+ int on = 1;
+ if (family == AF_INET6 && irc_in_addr_unspec(&local->addr))
setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on));
#endif
if (bind(fd, (struct sockaddr*)&addr, size)) {