Mercurial > dropbear
diff dbutil.c @ 297:79bf1023cf11 agent-client
propagate from branch 'au.asn.ucc.matt.dropbear' (head 0501e6f661b5415eb76f3b312d183c3adfbfb712)
to branch 'au.asn.ucc.matt.dropbear.cli-agent' (head 01038174ec27245b51bd43a66c01ad930880f67b)
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Tue, 21 Mar 2006 16:20:59 +0000 |
parents | ca7e76d981d9 044bc108b9b3 |
children | c1e9c81d1d27 |
line wrap: on
line diff
--- a/dbutil.c Mon Jul 18 14:32:52 2005 +0000 +++ b/dbutil.c Tue Mar 21 16:20:59 2006 +0000 @@ -110,6 +110,10 @@ exit(exitcode); } +void fail_assert(const char* expr, const char* file, int line) { + dropbear_exit("failed assertion (%s:%d): `%s'", file, line, expr); +} + static void generic_dropbear_log(int UNUSED(priority), const char* format, va_list param) { @@ -149,8 +153,33 @@ } #endif /* DEBUG_TRACE */ -/* Listen on address:port. Unless address is NULL, in which case listen on - * everything. If called with address == "", we'll listen on localhost/loopback. +static void set_sock_priority(int sock) { + + int val; + + /* disable nagle */ + val = 1; + setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (void*)&val, sizeof(val)); + + /* set the TOS bit. note that this will fail for ipv6, I can't find any + * equivalent. */ +#ifdef IPTOS_LOWDELAY + val = IPTOS_LOWDELAY; + setsockopt(sock, IPPROTO_IP, IP_TOS, (void*)&val, sizeof(val)); +#endif + +#ifdef SO_PRIORITY + /* linux specific, sets QoS class. + * 6 looks to be optimal for interactive traffic (see tc-prio(8) ). */ + val = 6; + setsockopt(sock, SOL_SOCKET, SO_PRIORITY, (void*) &val, sizeof(val)); +#endif + +} + +/* Listen on address:port. + * Special cases are address of "" listening on everything, + * and address of NULL listening on localhost only. * Returns the number of sockets bound on success, or -1 on failure. On * failure, if errstring wasn't NULL, it'll be a newly malloced error * string.*/ @@ -170,11 +199,17 @@ hints.ai_family = AF_UNSPEC; /* TODO: let them flag v4 only etc */ hints.ai_socktype = SOCK_STREAM; - if (address && address[0] == '\0') { + // for calling getaddrinfo: + // address == NULL and !AI_PASSIVE: local loopback + // address == NULL and AI_PASSIVE: all interfaces + // address != NULL: whatever the address says + if (!address) { TRACE(("dropbear_listen: local loopback")) - address = NULL; } else { - TRACE(("dropbear_listen: not local loopback")) + if (address[0] == '\0') { + TRACE(("dropbear_listen: all interfaces")) + address = NULL; + } hints.ai_flags = AI_PASSIVE; } err = getaddrinfo(address, port, &hints, &res0); @@ -186,6 +221,10 @@ *errstring = (char*)m_malloc(len); snprintf(*errstring, len, "Error resolving: %s", gai_strerror(err)); } + if (res0) { + freeaddrinfo(res0); + res0 = NULL; + } TRACE(("leave dropbear_listen: failed resolving")) return -1; } @@ -215,8 +254,7 @@ linger.l_linger = 5; setsockopt(sock, SOL_SOCKET, SO_LINGER, (void*)&linger, sizeof(linger)); - /* disable nagle */ - setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (void*)&val, sizeof(val)); + set_sock_priority(sock); if (bind(sock, res->ai_addr, res->ai_addrlen) < 0) { err = errno; @@ -237,6 +275,11 @@ nsock++; } + if (res0) { + freeaddrinfo(res0); + res0 = NULL; + } + if (nsock == 0) { if (errstring != NULL && *errstring == NULL) { int len; @@ -343,8 +386,7 @@ TRACE(("Error connecting: %s", strerror(err))) } else { /* Success */ - /* (err is used as a dummy var here) */ - setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (void*)&err, sizeof(err)); + set_sock_priority(sock); } freeaddrinfo(res0); @@ -555,20 +597,17 @@ } #endif -/* loop until the socket is closed (in case of EINTR) or - * we get and error. - * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */ -int m_close(int fd) { +/* make sure that the socket closes */ +void m_close(int fd) { int val; do { val = close(fd); } while (val < 0 && errno == EINTR); - if (val == 0 || errno == EBADF) { - return DROPBEAR_SUCCESS; - } else { - return DROPBEAR_FAILURE; + if (val < 0 && errno != EBADF) { + /* Linux says EIO can happen */ + dropbear_exit("Error closing fd %d, %s", fd, strerror(errno)); } }