# HG changeset patch
# User Dan Villiom Podlaski Christiansen <danchr@gmail.com>
# Date 1454621270 -3600
# Thu Feb 04 22:27:50 2016 +0100
# Node ID 1ea14c7448d2e9367c021c44222e02b253190f96
# Parent 45ed0847573d0b30ef796c6f58078b3baa76ab91
ayiya: handle EADDRNOTAVAIL when reading from UDP socket
AICCU uses a UDP socket for communicating with AYIYA servers. The
general idea is that this connection should be kept alive as long as
AICCU is running, and generally speaking this is true: As long as the
computer retains the IPv4 address used that socket bound to,
everything will work.
However, that assumption is no longer safe on modern laptops. They
tend to connect and disconnect from networks, and frequently have many
different IPv4 addresses as time passes.
On OS X, losing the socket IPv4 address results in reads failing
with errno set to EADDRNOTAVAIL. We handle this by simply recreating
the socket.
diff --git a/common/ayiya.c b/common/ayiya.c
a
|
b
|
void ayiya_log(int level, const char *wh |
77 | 77 | dolog(level, buf); |
78 | 78 | } |
79 | 79 | |
| 80 | static bool ayiya_reconnect(void); |
| 81 | static bool ayiya_reconnect(void) |
| 82 | { |
| 83 | char *addr = inet_ntoa(ayiya_ipv4_pop); |
| 84 | TLSSOCKET new_socket = connect_client(addr, AYIYA_PORT, AF_INET, SOCK_DGRAM); |
| 85 | |
| 86 | if (!new_socket) |
| 87 | { |
| 88 | ayiya_log(LOG_WARNING, reader_name, NULL, 0, "Error while reconnecting to AYIYA server %s: %s (%d)\n", addr, strerror(errno), errno); |
| 89 | |
| 90 | return false; |
| 91 | } |
| 92 | |
| 93 | ayiya_log(LOG_DEBUG, reader_name, NULL, 0, "Reconnected to server %s...\n", addr); |
| 94 | |
| 95 | sock_free(ayiya_socket); |
| 96 | ayiya_socket = new_socket; |
| 97 | |
| 98 | return true; |
| 99 | } |
| 100 | |
80 | 101 | /* Tun -> Socket */ |
81 | 102 | void ayiya_reader(char *buf, unsigned int length); |
82 | 103 | void ayiya_reader(char *buf, unsigned int length) |
… |
… |
void ayiya_reader(char *buf, unsigned in |
137 | 158 | if (lenout < 0) |
138 | 159 | { |
139 | 160 | ayiya_log(LOG_ERR, reader_name, NULL, 0, "Error (%d) while sending %u bytes to network: %s (%d)\n", lenout, length, strerror(errno), errno); |
| 161 | |
| 162 | #ifdef EADDRNOTAVAIL |
| 163 | if (errno == EADDRNOTAVAIL) |
| 164 | { |
| 165 | ayiya_reconnect(); |
| 166 | } |
| 167 | #endif |
140 | 168 | } |
141 | 169 | else if (length != (unsigned int)lenout) |
142 | 170 | { |
… |
… |
void ayiya_beat(void) |
335 | 363 | if (lenout < 0) |
336 | 364 | { |
337 | 365 | ayiya_log(LOG_ERR, beat_name, NULL, 0, "Error (%d) while sending %u bytes sent to network: %s (%d)\n", lenout, n, strerror(errno), errno); |
| 366 | |
| 367 | #ifdef EADDRNOTAVAIL |
| 368 | if (errno == EADDRNOTAVAIL) |
| 369 | { |
| 370 | ayiya_reconnect(); |
| 371 | } |
| 372 | #endif |
338 | 373 | } |
339 | 374 | else if (n != lenout) |
340 | 375 | { |