-int handle_new_meta_connection(int sock)
-{
- connection_t *c;
- sockaddr_t sa;
- int fd, len = sizeof(sa);
-cp
- if((fd = accept(sock, &sa.sa, &len)) < 0)
- {
- syslog(LOG_ERR, _("Accepting a new connection failed: %s"), strerror(errno));
- return -1;
- }
-
- sockaddrunmap(&sa);
-
- c = new_connection();
- c->outcipher = myself->connection->outcipher;
- c->outdigest = myself->connection->outdigest;
- c->outmaclength = myself->connection->outmaclength;
- c->outcompression = myself->connection->outcompression;
-
- c->address = sa;
- c->hostname = sockaddr2hostname(&sa);
- c->socket = fd;
- c->last_ping_time = now;
-
- if(debug_lvl >= DEBUG_CONNECTIONS)
- syslog(LOG_NOTICE, _("Connection from %s"), c->hostname);
-
- connection_add(c);
-
- c->allow_request = ID;
- send_id(c);
-cp
- return 0;
+void handle_new_meta_connection(void *data, int flags) {
+ listen_socket_t *l = data;
+ connection_t *c;
+ sockaddr_t sa;
+ int fd;
+ socklen_t len = sizeof sa;
+
+ fd = accept(l->tcp.fd, &sa.sa, &len);
+
+ if(fd < 0) {
+ logger(DEBUG_ALWAYS, LOG_ERR, "Accepting a new connection failed: %s", sockstrerror(sockerrno));
+ return;
+ }
+
+ sockaddrunmap(&sa);
+
+ // Check if we get many connections from the same host
+
+ static sockaddr_t prev_sa;
+ static time_t prev_time;
+ static int tarpit = -1;
+
+ if(tarpit >= 0) {
+ closesocket(tarpit);
+ tarpit = -1;
+ }
+
+ if(prev_time == now.tv_sec && !sockaddrcmp_noport(&sa, &prev_sa)) {
+ // if so, keep the connection open but ignore it completely.
+ tarpit = fd;
+ return;
+ }
+
+ memcpy(&prev_sa, &sa, sizeof sa);
+ prev_time = now.tv_sec;
+
+ // Check if we get many connections from different hosts
+
+ static int connection_burst;
+ static int connection_burst_time;
+
+ if(now.tv_sec - connection_burst_time > connection_burst)
+ connection_burst = 0;
+ else
+ connection_burst -= now.tv_sec - connection_burst_time;
+
+ connection_burst_time = now.tv_sec;
+ connection_burst++;
+
+ if(connection_burst >= max_connection_burst) {
+ connection_burst = max_connection_burst;
+ tarpit = fd;
+ return;
+ }
+
+ // Accept the new connection
+
+ c = new_connection();
+ c->name = xstrdup("<unknown>");
+ c->outcipher = myself->connection->outcipher;
+ c->outdigest = myself->connection->outdigest;
+ c->outmaclength = myself->connection->outmaclength;
+ c->outcompression = myself->connection->outcompression;
+
+ c->address = sa;
+ c->hostname = sockaddr2hostname(&sa);
+ c->socket = fd;
+ c->last_ping_time = now.tv_sec;
+
+ logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Connection from %s", c->hostname);
+
+ io_add(&c->io, handle_meta_io, c, c->socket, IO_READ);
+
+ configure_tcp(c);
+
+ connection_add(c);
+
+ c->allow_request = ID;
+ send_id(c);
+}
+
+#ifndef HAVE_MINGW
+/*
+ accept a new UNIX socket connection
+*/
+void handle_new_unix_connection(void *data, int flags) {
+ io_t *io = data;
+ connection_t *c;
+ sockaddr_t sa;
+ int fd;
+ socklen_t len = sizeof sa;
+
+ fd = accept(io->fd, &sa.sa, &len);
+
+ if(fd < 0) {
+ logger(DEBUG_ALWAYS, LOG_ERR, "Accepting a new connection failed: %s", sockstrerror(sockerrno));
+ return;
+ }
+
+ sockaddrunmap(&sa);
+
+ c = new_connection();
+ c->name = xstrdup("<control>");
+ c->address = sa;
+ c->hostname = xstrdup("localhost port unix");
+ c->socket = fd;
+ c->last_ping_time = now.tv_sec;
+
+ logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Connection from %s", c->hostname);
+
+ io_add(&c->io, handle_meta_io, c, c->socket, IO_READ);
+
+ connection_add(c);
+
+ c->allow_request = ID;
+
+ send_id(c);
+}
+#endif
+
+static void free_outgoing(outgoing_t *outgoing) {
+ timeout_del(&outgoing->ev);
+
+ if(outgoing->ai)
+ freeaddrinfo(outgoing->ai);
+
+ if(outgoing->config_tree)
+ exit_configuration(&outgoing->config_tree);
+
+ if(outgoing->name)
+ free(outgoing->name);
+
+ free(outgoing);