int seconds_till_retry = 5;
int udp_rcvbuf = 0;
int udp_sndbuf = 0;
+int max_connection_burst = 100;
listen_socket_t listen_socket[MAXSOCKETS];
int listen_sockets;
return true;
}
+static bool bind_to_address(connection_t *c) {
+ int s = -1;
+
+ for(int i = 0; i < listen_sockets; i++) {
+ if(listen_socket[i].sa.sa.sa_family != c->address.sa.sa_family)
+ continue;
+ if(s >= 0)
+ return false;
+ s = i;
+ }
+
+ if(s < 0)
+ return false;
+
+ sockaddr_t sa = listen_socket[s].sa;
+ if(sa.sa.sa_family == AF_INET)
+ sa.in.sin_port = 0;
+ else if(sa.sa.sa_family == AF_INET6)
+ sa.in6.sin6_port = 0;
+
+ if(bind(c->socket, &sa.sa, SALEN(sa.sa))) {
+ logger(DEBUG_CONNECTIONS, LOG_WARNING, "Can't bind outgoing socket: %s", strerror(errno));
+ return false;
+ }
+
+ return true;
+}
+
int setup_listen_socket(const sockaddr_t *sa) {
int nfd;
char *addrstr;
#endif
bind_to_interface(c->socket);
+ bind_to_address(c);
}
/* Connect */
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(!sockaddrcmp_noport(&sa, &prev_sa)) {
+ static int samehost_burst;
+ static int samehost_burst_time;
+
+ if(now.tv_sec - samehost_burst_time > samehost_burst)
+ samehost_burst = 0;
+ else
+ samehost_burst -= now.tv_sec - samehost_burst_time;
+
+ samehost_burst_time = now.tv_sec;
+ samehost_burst++;
+
+ if(samehost_burst > max_connection_burst) {
+ 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;