1) The sockaddr_t * returned may be part of memory freed by the call to
freeaddrinfo().
2) The sockaddr_t * returned from a recently seen address not in the
cache was cast from struct addrinfo *ai, not the struct sockaddr *
inside of it.
3) In do_outgoing_connection(), when filling in the address in the
connection_t, there is a buffer overflow (read, not write) if
the sa returned by get_recent_address() didn't come from the
cache of recently seen addresses. That is, it was really a
struct sockaddr * and not a sockaddr_t *. This last was
found by building tinc with address sanitizer.
if(cache->ai) {
if(cache->aip) {
if(cache->ai) {
if(cache->aip) {
- sockaddr_t *sa = (sockaddr_t *)cache->aip;
+ sockaddr_t *sa = (sockaddr_t *)cache->aip->ai_addr;
if(find_cached(cache, sa) != NOT_CACHED) {
continue;
if(find_cached(cache, sa) != NOT_CACHED) {
continue;
cache->cfg = lookup_config_next(cache->config_tree, cache->cfg);
}
cache->cfg = lookup_config_next(cache->config_tree, cache->cfg);
}
- if(cache->aip) {
- sockaddr_t *sa = (sockaddr_t *)cache->aip->ai_addr;
- cache->aip = cache->aip->ai_next;
+ if(cache->ai) {
+ if(cache->aip) {
+ sockaddr_t *sa = (sockaddr_t *)cache->aip->ai_addr;
+ cache->aip = cache->aip->ai_next;
+ return sa;
+ } else {
- cache->ai = cache->aip = NULL;
}
// We're all out of addresses.
}
// We're all out of addresses.
struct sockaddr_in in;
struct sockaddr_in6 in6;
struct sockaddr_unknown unknown;
struct sockaddr_in in;
struct sockaddr_in6 in6;
struct sockaddr_unknown unknown;
-#ifdef HAVE_STRUCT_SOCKADDR_STORAGE
- struct sockaddr_storage storage;
-#endif
} sockaddr_t;
#ifdef SA_LEN
} sockaddr_t;
#ifdef SA_LEN
int flags = fcntl(c->socket, F_GETFL);
if(fcntl(c->socket, F_SETFL, flags | O_NONBLOCK) < 0) {
int flags = fcntl(c->socket, F_GETFL);
if(fcntl(c->socket, F_SETFL, flags | O_NONBLOCK) < 0) {
- logger(DEBUG_ALWAYS, LOG_ERR, "fcntl for %s: %s", c->hostname, strerror(errno));
+ logger(DEBUG_ALWAYS, LOG_ERR, "fcntl for %s fd %d: %s", c->hostname, c->socket, strerror(errno));
}
#elif defined(WIN32)
unsigned long arg = 1;
if(ioctlsocket(c->socket, FIONBIO, &arg) != 0) {
}
#elif defined(WIN32)
unsigned long arg = 1;
if(ioctlsocket(c->socket, FIONBIO, &arg) != 0) {
- logger(DEBUG_ALWAYS, LOG_ERR, "ioctlsocket for %s: %s", c->hostname, sockstrerror(sockerrno));
+ logger(DEBUG_ALWAYS, LOG_ERR, "ioctlsocket for %s fd %d: %s", c->hostname, c->socket, sockstrerror(sockerrno));
connection_t *c = new_connection();
c->outgoing = outgoing;
connection_t *c = new_connection();
c->outgoing = outgoing;
+ memcpy(&c->address, sa, SALEN(sa->sa));
c->hostname = sockaddr2hostname(&c->address);
logger(DEBUG_CONNECTIONS, LOG_INFO, "Trying to connect to %s (%s)", outgoing->node->name, c->hostname);
c->hostname = sockaddr2hostname(&c->address);
logger(DEBUG_CONNECTIONS, LOG_INFO, "Trying to connect to %s (%s)", outgoing->node->name, c->hostname);