}
if(outgoing->state == OUTGOING_CANONICAL) {
- if(outgoing->aip || get_next_cfg(mesh, outgoing, "CanonicalAddress")) {
+ while(outgoing->aip || get_next_cfg(mesh, outgoing, "CanonicalAddress")) {
if(get_next_ai(mesh, outgoing)) {
return true;
} else {
}
if(outgoing->state == OUTGOING_RECENT) {
- if(outgoing->aip || get_next_cfg(mesh, outgoing, "Address")) {
+ while(outgoing->aip || get_next_cfg(mesh, outgoing, "Address")) {
if(get_next_ai(mesh, outgoing)) {
return true;
} else {
}
if(outgoing->state == OUTGOING_KNOWN) {
- if(outgoing->aip || get_recent(mesh, outgoing)) {
- if(get_next_ai(mesh, outgoing)) {
- return true;
- } else {
- free_known_addresses(outgoing->ai);
- outgoing->ai = NULL;
- outgoing->aip = NULL;
- }
+ if(!outgoing->aip) {
+ get_recent(mesh, outgoing);
+ } else {
+ outgoing->aip = outgoing->aip->ai_next;
+ }
+
+ if(outgoing->aip) {
+ return true;
+ } else {
+ free_known_addresses(outgoing->ai);
+ outgoing->ai = NULL;
+ outgoing->aip = NULL;
}
outgoing->state = OUTGOING_END;
}
if(c->socket == -1) {
- logger(mesh, MESHLINK_ERROR, "Creating socket for %s at %s failed: %s", c->name, c->hostname, sockstrerror(sockerrno));
+ logger(mesh, MESHLINK_ERROR, "Creating socket for %s at %s failed: %s", c->name, hostname, sockstrerror(sockerrno));
free_connection(c);
free(hostname);
goto begin;
return;
}
+ if(mesh->connection_try_cb) {
+ node_t *n = lookup_node(mesh, outgoing->name);
+ mesh->connection_try_cb(mesh, (struct meshlink_node *)n);
+ }
+
do_outgoing_connection(mesh, outgoing);
}
+/// Delayed close of a filedescriptor.
+static void tarpit(int fd) {
+ static int pits[10] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
+ static int next_pit = 0;
+
+ if(pits[next_pit] != -1) {
+ closesocket(pits[next_pit]);
+ }
+
+ pits[next_pit++] = fd;
+
+ if(next_pit >= (int)(sizeof pits / sizeof pits[0])) {
+ next_pit = 0;
+ }
+}
+
/*
accept a new tcp connect and create a
new connection
meshlink_handle_t *mesh = loop->data;
listen_socket_t *l = data;
connection_t *c;
- sockaddr_t sa = {0};
+ sockaddr_t sa;
int fd;
socklen_t len = sizeof(sa);
+ memset(&sa, 0, sizeof(sa));
+
fd = accept(l->tcp.fd, &sa.sa, &len);
if(fd < 0) {
sockaddrunmap(&sa);
- // Check if we get many connections from the same host
-
- static sockaddr_t prev_sa;
- static int tarpit = -1;
-
- if(tarpit >= 0) {
- closesocket(tarpit);
- tarpit = -1;
- }
-
- if(!sockaddrcmp_noport(&sa, &prev_sa)) {
- static int samehost_burst;
- static int samehost_burst_time;
-
- if(mesh->loop.now.tv_sec - samehost_burst_time > samehost_burst) {
- samehost_burst = 0;
- } else {
- samehost_burst -= mesh->loop.now.tv_sec - samehost_burst_time;
- }
-
- samehost_burst_time = mesh->loop.now.tv_sec;
- samehost_burst++;
-
- if(samehost_burst > max_connection_burst) {
- tarpit = fd;
- return;
- }
- }
-
- memcpy(&prev_sa, &sa, sizeof(sa));
-
- // Check if we get many connections from different hosts
+ /* Rate limit incoming connections to max_connection_burst/second. */
static int connection_burst;
static int connection_burst_time;
- if(mesh->loop.now.tv_sec - connection_burst_time > connection_burst) {
+ if(mesh->loop.now.tv_sec != connection_burst_time) {
+ connection_burst_time = mesh->loop.now.tv_sec;
connection_burst = 0;
- } else {
- connection_burst -= mesh->loop.now.tv_sec - connection_burst_time;
}
- connection_burst_time = mesh->loop.now.tv_sec;
- connection_burst++;
-
if(connection_burst >= max_connection_burst) {
- connection_burst = max_connection_burst;
- tarpit = fd;
+ tarpit(fd);
return;
}
+ connection_burst++;
+
// Accept the new connection
c = new_connection();
c->last_ping_time = mesh->loop.now.tv_sec;
char *hostname = sockaddr2hostname(&sa);
- logger(mesh, MESHLINK_INFO, "Connection from %s", c->hostname);
+ logger(mesh, MESHLINK_INFO, "Connection from %s", hostname);
free(hostname);
io_add(&mesh->loop, &c->io, handle_meta_io, c, c->socket, IO_READ);
if(!check_id(name)) {
logger(mesh, MESHLINK_ERROR,
- "Invalid name for outgoing connection in %s line %d",
- cfg->file, cfg->line);
+ "Invalid name for outgoing connection in line %d",
+ cfg->line);
free(name);
continue;
}