From e2e6ec8050274b0a8678d6fc263e7dc4ef66feae Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Sat, 13 Nov 2010 15:50:39 +0100 Subject: [PATCH 01/10] Provide usleep() for Windows. --- lib/dropin.c | 7 +++++++ lib/dropin.h | 4 ++++ 2 files changed, 11 insertions(+) diff --git a/lib/dropin.c b/lib/dropin.c index 89039da3..52fb5b86 100644 --- a/lib/dropin.c +++ b/lib/dropin.c @@ -163,3 +163,10 @@ int gettimeofday(struct timeval *tv, void *tz) { return 0; } #endif + +#ifdef HAVE_MINGW +int usleep(long usec) { + Sleep(usec / 1000); + return 0; +} +#endif diff --git a/lib/dropin.h b/lib/dropin.h index e9d13535..d5cf6d2c 100644 --- a/lib/dropin.h +++ b/lib/dropin.h @@ -41,4 +41,8 @@ extern int vasprintf(char **, const char *, va_list ap); extern int gettimeofday(struct timeval *, void *); #endif +#ifdef HAVE_MINGW +extern int usleep(long); +#endif + #endif /* __DROPIN_H__ */ From 9e3ca397735077f85bbde48c36e1b3e0fa950988 Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Sat, 13 Nov 2010 15:55:38 +0100 Subject: [PATCH 02/10] Use variable length arrays instead of alloca(). --- src/process.c | 2 +- src/protocol_auth.c | 13 ++++--------- src/protocol_key.c | 4 +--- 3 files changed, 6 insertions(+), 13 deletions(-) diff --git a/src/process.c b/src/process.c index f2fff1dc..b3054561 100644 --- a/src/process.c +++ b/src/process.c @@ -397,7 +397,7 @@ bool execute_script(const char *name, char **envp) { for(i = 0; envp[i]; i++) { char *e = strchr(envp[i], '='); if(e) { - p = alloca(e - envp[i] + 1); + p[e - envp[i] + 1]; strncpy(p, envp[i], e - envp[i]); p[e - envp[i]] = '\0'; putenv(p); diff --git a/src/protocol_auth.c b/src/protocol_auth.c index 3f4fa010..cde7ead9 100644 --- a/src/protocol_auth.c +++ b/src/protocol_auth.c @@ -109,15 +109,13 @@ bool id_h(connection_t *c) { } bool send_metakey(connection_t *c) { - char *buffer; - int len; bool x; - len = RSA_size(c->rsa_key); + int len = RSA_size(c->rsa_key); /* Allocate buffers for the meta key */ - buffer = alloca(2 * len + 1); + char buffer[2 * len + 1]; c->outkey = xrealloc(c->outkey, len); @@ -287,16 +285,13 @@ bool metakey_h(connection_t *c) { } bool send_challenge(connection_t *c) { - char *buffer; - int len; - /* CHECKME: what is most reasonable value for len? */ - len = RSA_size(c->rsa_key); + int len = RSA_size(c->rsa_key); /* Allocate buffers for the challenge */ - buffer = alloca(2 * len + 1); + char buffer[2 * len + 1]; c->hischallenge = xrealloc(c->hischallenge, len); diff --git a/src/protocol_key.c b/src/protocol_key.c index 22692bb6..b326b8d7 100644 --- a/src/protocol_key.c +++ b/src/protocol_key.c @@ -145,8 +145,6 @@ bool req_key_h(connection_t *c) { } bool send_ans_key(node_t *to) { - char *key; - // Set key parameters to->incipher = myself->incipher; to->inkeylength = myself->inkeylength; @@ -168,7 +166,7 @@ bool send_ans_key(node_t *to) { memset(to->late, 0, sizeof(to->late)); // Convert to hexadecimal and send - key = alloca(2 * to->inkeylength + 1); + char key[2 * to->inkeylength + 1]; bin2hex(to->inkey, key, to->inkeylength); key[to->inkeylength * 2] = '\0'; From 3f410e2f8f7c365630f226adf4904935698f9e0d Mon Sep 17 00:00:00 2001 From: Brandon L Black Date: Sat, 13 Nov 2010 12:05:48 -0600 Subject: [PATCH 03/10] Experimental IFF_ONE_QUEUE support for Linux --- doc/tinc.conf.5.in | 3 +++ src/linux/device.c | 7 +++++++ 2 files changed, 10 insertions(+) diff --git a/doc/tinc.conf.5.in b/doc/tinc.conf.5.in index 2bfd5fef..01f7f810 100644 --- a/doc/tinc.conf.5.in +++ b/doc/tinc.conf.5.in @@ -255,6 +255,9 @@ a lookup if your DNS server is not responding. This does not affect resolving hostnames to IP addresses from the host configuration files. +.It Va IffOneQueue Li = yes | no Po no Pc Bq experimental +(Linux only) Set IFF_ONE_QUEUE flag on TUN/TAP devices. + .It Va Interface Li = Ar interface Defines the name of the interface corresponding to the virtual network device. Depending on the operating system and the type of device this may or may not actually set the name of the interface. diff --git a/src/linux/device.c b/src/linux/device.c index 6c828c01..0632d51a 100644 --- a/src/linux/device.c +++ b/src/linux/device.c @@ -52,6 +52,7 @@ static uint64_t device_total_out = 0; bool setup_device(void) { struct ifreq ifr; + bool t1q = false; if(!get_config_string(lookup_config(config_tree, "Device"), &device)) device = xstrdup(DEFAULT_DEVICE); @@ -84,6 +85,12 @@ bool setup_device(void) { device_info = "Linux tun/tap device (tap mode)"; } +#ifdef IFF_ONE_QUEUE + /* Set IFF_ONE_QUEUE flag... */ + if(get_config_bool(lookup_config(config_tree, "IffOneQueue"), &t1q) && t1q) + ifr.ifr_flags |= IFF_ONE_QUEUE; +#endif + if(iface) strncpy(ifr.ifr_name, iface, IFNAMSIZ); From 8dfe1b374e165ecba5d3ae324ee834d337476be8 Mon Sep 17 00:00:00 2001 From: Brandon L Black Date: Sat, 13 Nov 2010 12:05:49 -0600 Subject: [PATCH 04/10] Configurable SO_RCVBUF/SO_SNDBUF for the UDP socket --- doc/tinc.conf.5.in | 8 ++++++++ src/net.h | 2 ++ src/net_setup.c | 14 ++++++++++++++ src/net_socket.c | 8 ++++++++ 4 files changed, 32 insertions(+) diff --git a/doc/tinc.conf.5.in b/doc/tinc.conf.5.in index 01f7f810..66aee4b6 100644 --- a/doc/tinc.conf.5.in +++ b/doc/tinc.conf.5.in @@ -356,6 +356,14 @@ and will only allow connections with nodes for which host config files are prese .Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /hosts/ directory. Setting this options also implicitly sets StrictSubnets. + +.It Va UDPRcvBuf Li = Ar bytes Pq OS default +Sets the socket receive buffer size for the UDP socket, in bytes. +If unset, the default buffer size will be used by the operating system. + +.It Va UDPSndBuf Li = Ar bytes Pq OS default +Sets the socket send buffer size for the UDP socket, in bytes. +If unset, the default buffer size will be used by the operating system. .El .Sh HOST CONFIGURATION FILES diff --git a/src/net.h b/src/net.h index eae979cd..8c92fc3e 100644 --- a/src/net.h +++ b/src/net.h @@ -111,6 +111,8 @@ extern listen_socket_t listen_socket[MAXSOCKETS]; extern int listen_sockets; extern int keyexpires; extern int keylifetime; +extern int udp_rcvbuf; +extern int udp_sndbuf; extern bool do_prune; extern bool do_purge; extern char *myport; diff --git a/src/net_setup.c b/src/net_setup.c index f4e56378..e7d3e40b 100644 --- a/src/net_setup.c +++ b/src/net_setup.c @@ -405,6 +405,20 @@ bool setup_myself(void) { } else maxtimeout = 900; + if(get_config_int(lookup_config(config_tree, "UDPRcvBuf"), &udp_rcvbuf)) { + if(udp_rcvbuf <= 0) { + logger(LOG_ERR, "UDPRcvBuf cannot be negative!"); + return false; + } + } + + if(get_config_int(lookup_config(config_tree, "UDPSndBuf"), &udp_sndbuf)) { + if(udp_sndbuf <= 0) { + logger(LOG_ERR, "UDPSndBuf cannot be negative!"); + return false; + } + } + if(get_config_string(lookup_config(config_tree, "AddressFamily"), &afname)) { if(!strcasecmp(afname, "IPv4")) addressfamily = AF_INET; diff --git a/src/net_socket.c b/src/net_socket.c index 762c0a22..20029e87 100644 --- a/src/net_socket.c +++ b/src/net_socket.c @@ -44,6 +44,8 @@ int addressfamily = AF_UNSPEC; int maxtimeout = 900; int seconds_till_retry = 5; +int udp_rcvbuf = 0; +int udp_sndbuf = 0; listen_socket_t listen_socket[MAXSOCKETS]; int listen_sockets; @@ -261,6 +263,12 @@ int setup_vpn_in_socket(const sockaddr_t *sa) { option = 1; setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, (void *)&option, sizeof(option)); + if(udp_rcvbuf && setsockopt(nfd, SOL_SOCKET, SO_RCVBUF, (void *)&udp_rcvbuf, sizeof(udp_rcvbuf))) + logger(LOG_WARNING, "Can't set UDP SO_RCVBUF to %i: %s", option, strerror(errno)); + + if(udp_sndbuf && setsockopt(nfd, SOL_SOCKET, SO_SNDBUF, (void *)&udp_sndbuf, sizeof(udp_sndbuf))) + logger(LOG_WARNING, "Can't set UDP SO_SNDBUF to %i: %s", option, strerror(errno)); + #if defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY) if(sa->sa.sa_family == AF_INET6) setsockopt(nfd, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&option, sizeof option); From 23acc19bc090051156ad895caed61848f5afb144 Mon Sep 17 00:00:00 2001 From: Brandon L Black Date: Sat, 13 Nov 2010 12:05:50 -0600 Subject: [PATCH 05/10] Configurable ReplayWindow size, zero disables --- doc/tinc.conf.5.in | 10 ++++++++++ src/net.h | 1 + src/net_packet.c | 36 ++++++++++++++++++++---------------- src/net_setup.c | 9 +++++++++ src/node.c | 1 + src/node.h | 2 +- src/protocol_key.c | 2 +- 7 files changed, 43 insertions(+), 18 deletions(-) diff --git a/doc/tinc.conf.5.in b/doc/tinc.conf.5.in index 66aee4b6..ce690308 100644 --- a/doc/tinc.conf.5.in +++ b/doc/tinc.conf.5.in @@ -344,6 +344,16 @@ specified in the configuration file. When this option is used the priority of the tincd process will be adjusted. Increasing the priority may help to reduce latency and packet loss on the VPN. +.It Va ReplayWindow Li = Ar bytes Pq 16 +This is the size of the replay tracking window for each remote node, in bytes. +The window is a bitfield which tracks 1 packet per bit, so for example +the default setting of 16 will track up to 128 packets in the window. In high +bandwidth scenarios, setting this to a higher value can reduce packet loss from +the interaction of replay tracking with underlying real packet loss and/or +reordering. Setting this to zero will disable replay tracking completely and +pass all traffic, but leaves tinc vulnerable to replay-based attacks on your +traffic. + .It Va StrictSubnets Li = yes | no Po no Pc Bq experimental When this option is enabled tinc will only use Subnet statements which are present in the host config files in the local diff --git a/src/net.h b/src/net.h index 8c92fc3e..55856e2b 100644 --- a/src/net.h +++ b/src/net.h @@ -106,6 +106,7 @@ extern list_t *outgoing_list; extern int maxoutbufsize; extern int seconds_till_retry; extern int addressfamily; +extern unsigned replaywin; extern listen_socket_t listen_socket[MAXSOCKETS]; extern int listen_sockets; diff --git a/src/net_packet.c b/src/net_packet.c index 44ab55d4..b35f72d4 100644 --- a/src/net_packet.c +++ b/src/net_packet.c @@ -60,6 +60,8 @@ static char lzo_wrkmem[LZO1X_999_MEM_COMPRESS > LZO1X_1_MEM_COMPRESS ? LZO1X_999 static void send_udppacket(node_t *, vpn_packet_t *); +unsigned replaywin = 16; + #define MAX_SEQNO 1073741824 // mtuprobes == 1..30: initial discovery, send bursts with 1 second interval @@ -293,25 +295,27 @@ static void receive_udppacket(node_t *n, vpn_packet_t *inpkt) { inpkt->len -= sizeof(inpkt->seqno); inpkt->seqno = ntohl(inpkt->seqno); - if(inpkt->seqno != n->received_seqno + 1) { - if(inpkt->seqno >= n->received_seqno + sizeof(n->late) * 8) { - logger(LOG_WARNING, "Lost %d packets from %s (%s)", - inpkt->seqno - n->received_seqno - 1, n->name, n->hostname); - - memset(n->late, 0, sizeof(n->late)); - } else if (inpkt->seqno <= n->received_seqno) { - if((n->received_seqno >= sizeof(n->late) * 8 && inpkt->seqno <= n->received_seqno - sizeof(n->late) * 8) || !(n->late[(inpkt->seqno / 8) % sizeof(n->late)] & (1 << inpkt->seqno % 8))) { - logger(LOG_WARNING, "Got late or replayed packet from %s (%s), seqno %d, last received %d", - n->name, n->hostname, inpkt->seqno, n->received_seqno); - return; + if(replaywin) { + if(inpkt->seqno != n->received_seqno + 1) { + if(inpkt->seqno >= n->received_seqno + replaywin * 8) { + logger(LOG_WARNING, "Lost %d packets from %s (%s)", + inpkt->seqno - n->received_seqno - 1, n->name, n->hostname); + + memset(n->late, 0, replaywin); + } else if (inpkt->seqno <= n->received_seqno) { + if((n->received_seqno >= replaywin * 8 && inpkt->seqno <= n->received_seqno - replaywin * 8) || !(n->late[(inpkt->seqno / 8) % replaywin] & (1 << inpkt->seqno % 8))) { + logger(LOG_WARNING, "Got late or replayed packet from %s (%s), seqno %d, last received %d", + n->name, n->hostname, inpkt->seqno, n->received_seqno); + return; + } + } else { + for(i = n->received_seqno + 1; i < inpkt->seqno; i++) + n->late[(i / 8) % replaywin] |= 1 << i % 8; } - } else { - for(i = n->received_seqno + 1; i < inpkt->seqno; i++) - n->late[(i / 8) % sizeof(n->late)] |= 1 << i % 8; } - } - n->late[(inpkt->seqno / 8) % sizeof(n->late)] &= ~(1 << inpkt->seqno % 8); + n->late[(inpkt->seqno / 8) % replaywin] &= ~(1 << inpkt->seqno % 8); + } if(inpkt->seqno > n->received_seqno) n->received_seqno = inpkt->seqno; diff --git a/src/net_setup.c b/src/net_setup.c index e7d3e40b..b46d1ae5 100644 --- a/src/net_setup.c +++ b/src/net_setup.c @@ -276,6 +276,7 @@ bool setup_myself(void) { struct addrinfo *ai, *aip, hint = {0}; bool choice; int i, err; + int replaywin_int; myself = new_node(); myself->connection = new_connection(); @@ -419,6 +420,14 @@ bool setup_myself(void) { } } + if(get_config_int(lookup_config(config_tree, "ReplayWindow"), &replaywin_int)) { + if(replaywin_int < 0) { + logger(LOG_ERR, "ReplayWindow cannot be negative!"); + return false; + } + replaywin = (unsigned)replaywin_int; + } + if(get_config_string(lookup_config(config_tree, "AddressFamily"), &afname)) { if(!strcasecmp(afname, "IPv4")) addressfamily = AF_INET; diff --git a/src/node.c b/src/node.c index b323dca3..a533cee6 100644 --- a/src/node.c +++ b/src/node.c @@ -54,6 +54,7 @@ void exit_nodes(void) { node_t *new_node(void) { node_t *n = xmalloc_and_zero(sizeof(*n)); + if(replaywin) n->late = xmalloc_and_zero(replaywin); n->subnet_tree = new_subnet_tree(); n->edge_tree = new_edge_tree(); EVP_CIPHER_CTX_init(&n->inctx); diff --git a/src/node.h b/src/node.h index 83e89c7d..de0f8c83 100644 --- a/src/node.h +++ b/src/node.h @@ -77,7 +77,7 @@ typedef struct node_t { uint32_t sent_seqno; /* Sequence number last sent to this node */ uint32_t received_seqno; /* Sequence number last received from this node */ - unsigned char late[16]; /* Bitfield marking late packets */ + unsigned char* late; /* Bitfield marking late packets */ length_t mtu; /* Maximum size of packets to send to this node */ length_t minmtu; /* Probed minimum MTU */ diff --git a/src/protocol_key.c b/src/protocol_key.c index b326b8d7..fbd7cabb 100644 --- a/src/protocol_key.c +++ b/src/protocol_key.c @@ -163,7 +163,7 @@ bool send_ans_key(node_t *to) { // Reset sequence number and late packet window mykeyused = true; to->received_seqno = 0; - memset(to->late, 0, sizeof(to->late)); + if(replaywin) memset(to->late, 0, replaywin); // Convert to hexadecimal and send char key[2 * to->inkeylength + 1]; From 0d61d4ae1358553fc8dde350747542f137f5cb8b Mon Sep 17 00:00:00 2001 From: Brandon L Black Date: Sat, 13 Nov 2010 12:05:51 -0600 Subject: [PATCH 06/10] Improved handling of queue-jumping packets on receive --- src/net_packet.c | 9 +++++++-- src/node.h | 1 + 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/net_packet.c b/src/net_packet.c index b35f72d4..9c551299 100644 --- a/src/net_packet.c +++ b/src/net_packet.c @@ -298,9 +298,13 @@ static void receive_udppacket(node_t *n, vpn_packet_t *inpkt) { if(replaywin) { if(inpkt->seqno != n->received_seqno + 1) { if(inpkt->seqno >= n->received_seqno + replaywin * 8) { + if(n->farfuture++ < replaywin >> 2) { + logger(LOG_WARNING, "Packet from %s (%s) is %d seqs in the future, dropped (%u)", + n->name, n->hostname, inpkt->seqno - n->received_seqno - 1, n->farfuture); + return; + } logger(LOG_WARNING, "Lost %d packets from %s (%s)", inpkt->seqno - n->received_seqno - 1, n->name, n->hostname); - memset(n->late, 0, replaywin); } else if (inpkt->seqno <= n->received_seqno) { if((n->received_seqno >= replaywin * 8 && inpkt->seqno <= n->received_seqno - replaywin * 8) || !(n->late[(inpkt->seqno / 8) % replaywin] & (1 << inpkt->seqno % 8))) { @@ -313,7 +317,8 @@ static void receive_udppacket(node_t *n, vpn_packet_t *inpkt) { n->late[(i / 8) % replaywin] |= 1 << i % 8; } } - + + n->farfuture = 0; n->late[(inpkt->seqno / 8) % replaywin] &= ~(1 << inpkt->seqno % 8); } diff --git a/src/node.h b/src/node.h index de0f8c83..7bac28e3 100644 --- a/src/node.h +++ b/src/node.h @@ -77,6 +77,7 @@ typedef struct node_t { uint32_t sent_seqno; /* Sequence number last sent to this node */ uint32_t received_seqno; /* Sequence number last received from this node */ + uint32_t farfuture; /* Packets in a row that have arrived from the far future */ unsigned char* late; /* Bitfield marking late packets */ length_t mtu; /* Maximum size of packets to send to this node */ From a9445e38f25bd24eca289768fc46e44e36b842ac Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Sat, 13 Nov 2010 21:34:59 +0100 Subject: [PATCH 07/10] Fix warning message when setting SO_RCVBUF or SO_SNDBUF fails. --- src/net_socket.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/net_socket.c b/src/net_socket.c index 20029e87..2e6b0685 100644 --- a/src/net_socket.c +++ b/src/net_socket.c @@ -264,10 +264,10 @@ int setup_vpn_in_socket(const sockaddr_t *sa) { setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, (void *)&option, sizeof(option)); if(udp_rcvbuf && setsockopt(nfd, SOL_SOCKET, SO_RCVBUF, (void *)&udp_rcvbuf, sizeof(udp_rcvbuf))) - logger(LOG_WARNING, "Can't set UDP SO_RCVBUF to %i: %s", option, strerror(errno)); + logger(LOG_WARNING, "Can't set UDP SO_RCVBUF to %i: %s", udp_rcvbuf, strerror(errno)); if(udp_sndbuf && setsockopt(nfd, SOL_SOCKET, SO_SNDBUF, (void *)&udp_sndbuf, sizeof(udp_sndbuf))) - logger(LOG_WARNING, "Can't set UDP SO_SNDBUF to %i: %s", option, strerror(errno)); + logger(LOG_WARNING, "Can't set UDP SO_SNDBUF to %i: %s", udp_sndbuf, strerror(errno)); #if defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY) if(sa->sa.sa_family == AF_INET6) From 5eb0440110f99f0a49838cc00a0686c7a7595663 Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Sat, 13 Nov 2010 21:36:51 +0100 Subject: [PATCH 08/10] Free replay window when freeing a node_t. --- src/node.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/node.c b/src/node.c index a533cee6..7bcad892 100644 --- a/src/node.c +++ b/src/node.c @@ -92,6 +92,9 @@ void free_node(node_t *n) { if(n->name) free(n->name); + if(n->late) + free(n->late); + free(n); } From e764ff7be9949c91865aff72844357e76ae6dd78 Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Tue, 16 Nov 2010 16:45:36 +0100 Subject: [PATCH 09/10] Fix variable length array declaration. --- src/process.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/process.c b/src/process.c index b3054561..0007943a 100644 --- a/src/process.c +++ b/src/process.c @@ -356,7 +356,7 @@ bool detach(void) { bool execute_script(const char *name, char **envp) { #ifdef HAVE_SYSTEM int status, len; - char *scriptname, *p; + char *scriptname; int i; #ifndef HAVE_MINGW @@ -397,7 +397,7 @@ bool execute_script(const char *name, char **envp) { for(i = 0; envp[i]; i++) { char *e = strchr(envp[i], '='); if(e) { - p[e - envp[i] + 1]; + char p[e - envp[i] + 1]; strncpy(p, envp[i], e - envp[i]); p[e - envp[i]] = '\0'; putenv(p); From d91903ef3c2a1f4481ae8757bb2b14282f2b7e68 Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Tue, 16 Nov 2010 17:28:41 +0100 Subject: [PATCH 10/10] Attribution for Brandon Black. --- AUTHORS | 1 + THANKS | 1 + src/net_packet.c | 1 + src/net_setup.c | 1 + 4 files changed, 4 insertions(+) diff --git a/AUTHORS b/AUTHORS index 3f1ebacf..e4189967 100644 --- a/AUTHORS +++ b/AUTHORS @@ -10,6 +10,7 @@ Significant contributions from: - Scott Lamb - Julien Muchembled - Timothy Redaelli +- Brandon Black These files are from other sources: * lib/pidfile.h and lib/pidfile.c are by Martin Schulze, taken from diff --git a/THANKS b/THANKS index 601116ef..d312dadb 100644 --- a/THANKS +++ b/THANKS @@ -4,6 +4,7 @@ We would like to thank the following people for their contributions to tinc: * Allesandro Gatti * Andreas van Cranenburgh * Armijn Hemel +* Brandon Black * Cris van Pelt * Delf Eldkraft * dnk diff --git a/src/net_packet.c b/src/net_packet.c index 9c551299..9e5ef465 100644 --- a/src/net_packet.c +++ b/src/net_packet.c @@ -3,6 +3,7 @@ Copyright (C) 1998-2005 Ivo Timmermans, 2000-2010 Guus Sliepen 2010 Timothy Redaelli + 2010 Brandon Black This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/net_setup.c b/src/net_setup.c index b46d1ae5..cc6ef680 100644 --- a/src/net_setup.c +++ b/src/net_setup.c @@ -3,6 +3,7 @@ Copyright (C) 1998-2005 Ivo Timmermans, 2000-2010 Guus Sliepen 2006 Scott Lamb + 2010 Brandon Black This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by