X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=net.c;h=543485e75c084a19ded62eff4f0393c29a157955;hp=e21f40293e591831dfcc64c7f4b236010e6e60b3;hb=62414974b55d78a67d4170da85091a915087219f;hpb=d080286b39f943baf22f1b531816d8209d8685d6 diff --git a/net.c b/net.c index e21f4029..543485e7 100644 --- a/net.c +++ b/net.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2007 Andre Noll + * Copyright (C) 2005-2008 Andre Noll * * Licensed under the GPL v2. For licencing details see COPYING. */ @@ -147,10 +147,11 @@ int makesock(unsigned l3type, unsigned l4type, int passive, { struct addrinfo *local = NULL, *src, *remote = NULL, *dst, hints; - char *port = make_message("%u", port_number); int rc, on = 1, sockfd = -1, socktype = sock_type(l4type); + char port[6]; /* port number has at most 5 digits */ + sprintf(port, "%u", port_number); /* Set up address hint structure */ memset(&hints, 0, sizeof(hints)); hints.ai_family = l3type; @@ -171,7 +172,7 @@ int makesock(unsigned l3type, unsigned l4type, int passive, if ((rc = getaddrinfo(host, port, &hints, passive ? &local : &remote))) { PARA_ERROR_LOG("can not resolve %s address %s#%s: %s.\n", layer4_name(l4type), - host? : (passive? "[loopback]" : "[localhost]"), + host? host : (passive? "[loopback]" : "[localhost]"), port, gai_strerror(rc)); return -E_ADDRESS_LOOKUP; } @@ -225,7 +226,7 @@ get_next_src: if (src == NULL && dst == NULL) { PARA_ERROR_LOG("can not create %s socket %s#%s.\n", - layer4_name(l4type), host? : (passive? + layer4_name(l4type), host? host : (passive? "[loopback]" : "[localhost]"), port); return -ERRNO_TO_PARA_ERROR(errno); } @@ -268,7 +269,7 @@ int para_listen(unsigned l3type, unsigned l4type, unsigned short port) * * \sa getnameinfo(3). */ -char *host_and_port(struct sockaddr *sa, socklen_t len) +static char *host_and_port(struct sockaddr *sa, socklen_t len) { static char output[NI_MAXHOST + NI_MAXSERV + 2]; char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV]; @@ -276,12 +277,12 @@ char *host_and_port(struct sockaddr *sa, socklen_t len) ret = getnameinfo(sa, len, hbuf, sizeof(hbuf), sbuf, sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV); - if (ret) { - PARA_WARNING_LOG("hostname lookup error (%s).\n", gai_strerror(ret)); + if (ret) { + PARA_WARNING_LOG("hostname lookup error (%s).\n", + gai_strerror(ret)); sprintf(output, "(unknown)"); - } else { + } else sprintf(output, "%s#%s", hbuf, sbuf); - } return output; } @@ -312,7 +313,7 @@ static char *__get_sock_name(int fd, int (*getname)(int, struct sockaddr*, return host_and_port((struct sockaddr *)&ss, sslen); } -char *local_name(int sockfd) +char *local_name(int sockfd) { return __get_sock_name(sockfd, getsockname); } @@ -322,6 +323,28 @@ char *remote_name(int sockfd) return __get_sock_name(sockfd, getpeername); } +/** + * Extract IPv4 or IPv6-mapped-IPv4 address from sockaddr_storage. + * \param ss Container of IPv4/6 address + * \return Extracted IPv4 address (different from 0) or 0 if unsuccessful. + * + * \sa RFC 3493 + */ +struct in_addr extract_v4_addr(const struct sockaddr_storage *ss) +{ + struct in_addr ia = {.s_addr = 0}; + + if (ss->ss_family == AF_INET) + ia.s_addr = ((struct sockaddr_in *)ss)->sin_addr.s_addr; + if (ss->ss_family == AF_INET6) { + const struct in6_addr v6_addr = ((struct sockaddr_in6 *)ss)->sin6_addr; + + if (IN6_IS_ADDR_V4MAPPED(&v6_addr)) + memcpy(&ia.s_addr, &(v6_addr.s6_addr[12]), 4); + } + return ia; +} + /* * Send out a buffer, resend on short writes. * @@ -339,7 +362,7 @@ static int sendall(int fd, const char *buf, size_t *len) assert(total); *len = 0; while (*len < total) { - int ret = send(fd, buf + *len, total - *len, 0); + int ret = write(fd, buf + *len, total - *len); if (ret == -1) return -ERRNO_TO_PARA_ERROR(errno); *len += ret;