#include <stdlib.h>
/* Log helper function: create "host:port" string from socket address: */
-static char *addr2str(const struct sockaddr *addr, socklen_t addrlen) {
- char host[64], svc[10], *s;
+static char *addr2str(const struct sockaddr *addr, socklen_t addrlen,
+ char *buf, size_t bufsize) {
+ char host[64], svc[10];
int err;
err = getnameinfo(addr, addrlen, host, sizeof host, svc, sizeof svc,
- NI_NUMERICHOST | NI_NUMERICSERV);
- if (err != 0) {
- strcpy(host, "<?>");
- strcpy(svc, "<?>");
- }
- s = malloc(strlen(host) + strlen(svc) + 2);
- if (s != NULL)
- sprintf(s, "%s:%s", host, svc);
- return s;
+ NI_NUMERICHOST | NI_NUMERICSERV);
+ if (err == 0)
+ snprintf(buf, bufsize, "%s:%s", host, svc);
+ else
+ snprintf(buf, bufsize, "<?>:<?>");
+ return buf;
}
-#define GET_STRADDR(s_,a_,l_) char *(s_) = addr2str((a_),(l_))
-#define FREE_STRADDR(s_) free(s_)
+#define ADDR2STR(a_,l_,b_,s_) char (b_)[(s_)]; addr2str((a_),(l_),(b_),(s_))
#define NETLOG_MSG(fi_,fn_,ln_,...) do { \
fprintf(stderr,"%s:%s@%d: ",fi_,fn_,ln_); \
#endif
#else
-#define GET_STRADDR(...)
-#define FREE_STRADDR(...)
+#define ADDR2STR(...)
#define NETLOG_ERR(...)
#define NETLOG_DBG(...)
#endif /* NET_ERR */
return err;
}
for (struct addrinfo *ai = info; ai != NULL; ai = ai->ai_next) {
+ ADDR2STR(ai->ai_addr, ai->ai_addrlen, stra, 100);
err = bind(sock, ai->ai_addr, ai->ai_addrlen);
if (err != 0) {
- GET_STRADDR(straddr_, ai->ai_addr, ai->ai_addrlen);
- NETLOG_ERR(EAI_SYSTEM, "bind(%d, %s)", sock, straddr_);
- FREE_STRADDR(straddr_);
+ NETLOG_ERR(EAI_SYSTEM, "bind(%d, %s)", sock, stra);
continue;
}
else {
- GET_STRADDR(straddr_, ai->ai_addr, ai->ai_addrlen);
- NETLOG_DBG("bind(%d, %s): Ok", sock, straddr_);
- FREE_STRADDR(straddr_);
+ NETLOG_DBG("bind(%d, %s): Ok", sock, stra);
}
break;
}
sock = -1;
continue;
}
+ ADDR2STR(ai->ai_addr, ai->ai_addrlen, stra, 100);
err = bind(sock, ai->ai_addr, ai->ai_addrlen);
if (err != 0) {
- GET_STRADDR(straddr_, ai->ai_addr, ai->ai_addrlen);
- NETLOG_ERR(EAI_SYSTEM, "bind(%d, %s)", sock, straddr_);
- FREE_STRADDR(straddr_);
+ NETLOG_ERR(EAI_SYSTEM, "bind(%d, %s)", sock, stra);
close(sock);
sock = -1;
continue;
}
else {
- GET_STRADDR(straddr_, ai->ai_addr, ai->ai_addrlen);
- NETLOG_DBG("bind(%d, %s): Ok", sock, straddr_);
- FREE_STRADDR(straddr_);
+ NETLOG_DBG("bind(%d, %s): Ok", sock, stra);
}
break;
}
sock = -1;
continue;
}
+ ADDR2STR(ai->ai_addr, ai->ai_addrlen, stra, 100);
err = connect(sock, ai->ai_addr, ai->ai_addrlen);
if (err != 0) {
- GET_STRADDR(straddr_, ai->ai_addr, ai->ai_addrlen);
- NETLOG_ERR(EAI_SYSTEM, "connect(%d, %s)", sock, straddr_);
- FREE_STRADDR(straddr_);
+ NETLOG_ERR(EAI_SYSTEM, "connect(%d, %s)", sock, stra);
close(sock);
sock = -1;
continue;
}
else {
- GET_STRADDR(straddr_, ai->ai_addr, ai->ai_addrlen);
- NETLOG_DBG("connect(%d, %s): Ok", sock, straddr_);
- FREE_STRADDR(straddr_);
+ NETLOG_DBG("connect(%d, %s): Ok", sock, stra);
}
break;
}
r = EAI_SYSTEM;
}
else {
- GET_STRADDR(straddr_, addr, addrlen);
- NETLOG_DBG("accept(%d) -> (%d, %s): Ok", sock, r, straddr_);
- FREE_STRADDR(straddr_);
+ ADDR2STR(addr, addrlen, stra, 100);
+ NETLOG_DBG("accept(%d) -> (%d, %s): Ok", sock, r, stra);
}
}
else if (r == 0) {
- errno = ETIMEDOUT;
+ errno = ETIME;
r = EAI_SYSTEM;
}
else if (r < 0) {
* st - <int> socket type; one of SOCK_STREAM or SOCK_DGRAM
* af - <int> address family; one of AF_UNSPEC, AF_INET, AF_INET6
*
- * Note: Address family AF_INET6 will still allow V4MAPPED connections.
+ * Note: Address family AF_INET6 will allow mapped IPv4 connections.
* AF_UNSPEC will cause the first suitable bind address to be used,
* the sort order is determined by the host configuration, e.g. in
* /etc/gai.conf for glibc.
* sock - <int> TCP listener socket
* timeout - <int> timeout in milliseconds
*
- * Note: A time-out condition is considered an error, and errno is set
- * to ETIMEDOUT. A negative value for timeout will cause tcp_accept()
- * to wait indefinitely. Set the timeout to zero for immediate and
- * non-blocking operation.
+ * Note: When the time-out expires a negative value is returned and
+ * errno is set to ETIME. A negative value for timeout will cause
+ * tcp_accept() to wait indefinitely. Set timeout to zero for
+ * non-blocking operation (immediate return).
*/
extern int tcp_accept(int sock, int timeout);