]> git.meshlink.io Git - meshlink/commitdiff
Merge branch 'master' into 1.1
authorGuus Sliepen <guus@tinc-vpn.org>
Sat, 17 Apr 2010 10:21:53 +0000 (12:21 +0200)
committerGuus Sliepen <guus@tinc-vpn.org>
Sat, 17 Apr 2010 10:21:53 +0000 (12:21 +0200)
Conflicts:
NEWS
README
configure.in
src/net.c
src/net.h

14 files changed:
NEWS
THANKS
doc/tinc.conf.5.in
doc/tinc.texi
src/conf.c
src/ipv4.h
src/ipv6.h
src/net.c
src/net.h
src/net_setup.c
src/netutl.c
src/protocol_auth.c
src/route.c
src/subnet.h

diff --git a/NEWS b/NEWS
index 3b06596968f0a43638801fb2968de4e40f8b6b10..cee37ea824ca32fb6835e76a00f8a2f1d38ef4c3 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,22 @@ Version 1.1-cvs              Work in progress
 
  * Use splay trees instead of AVL trees.
 
+Version 1.0.14               not released yet
+
+ * Fixed reading configuration files that do not end with a newline. Again.
+
+Version 1.0.13               Apr 11 2010
+
+ * Allow building tinc without LZO and/or Zlib.
+
+ * Clamp MSS of TCP packets in both directions.
+
+ * Experimental StrictSubnets, Forwarding and DirectOnly options,
+   giving more control over information and packets received from/sent to other
+   nodes.
+
+ * Ensure tinc never sends symbolic names for ports over the wire.
+
 Version 1.0.12               Feb  3 2010
 
  * Really allow fast roaming of hosts to other nodes in a switched VPN.
diff --git a/THANKS b/THANKS
index e0d33d3f18b1d6522e1195c59a518b8134aae907..08f17d58bee4256d54ce27f6954e2586e98bccbd 100644 (file)
--- a/THANKS
+++ b/THANKS
@@ -34,6 +34,7 @@ We would like to thank the following people for their contributions to tinc:
 * Scott Lamb
 * Sven-Haegar Koch
 * Teemu Kiviniemi
+* Timothy Redaelli
 * Tonnerre Lombard
 * Wessel Dankers
 * Wouter van Heyst
index 8f5237f7d19a4dd1c9c8b750d87a134831cc6f57..bc82b17637443a7708b1f470804b1a39c9a4f81d 100644 (file)
@@ -199,13 +199,13 @@ Tinc will expect packets read from the virtual network device
 to start with an Ethernet header.
 .El
 
-.It Va DirectOnly Li = yes | no Pq no
+.It Va DirectOnly Li = yes | no Po no Pc Bq experimental
 When this option is enabled, packets that cannot be sent directly to the destination node,
 but which would have to be forwarded by an intermediate node, are dropped instead.
 When combined with the IndirectData option,
 packets for nodes for which we do not have a meta connection with are also dropped.
 
-.It Va Forwarding Li = off | internal | kernel Pq internal
+.It Va Forwarding Li = off | internal | kernel Po internal Pc Bq experimental
 This option selects the way indirect packets are forwarded.
 .Bl -tag -width indent
 
index f4b98dd76b3532cd13c05a072a9e042d1d9c57cc..a5ef8e6c4812c1be05d188839ef3b5eb76663bf5 100644 (file)
@@ -843,14 +843,14 @@ to start with an Ethernet header.
 @end table
 
 @cindex DirectOnly
-@item DirectOnly = <yes|no> (no)
+@item DirectOnly = <yes|no> (no) [experimental]
 When this option is enabled, packets that cannot be sent directly to the destination node,
 but which would have to be forwarded by an intermediate node, are dropped instead.
 When combined with the IndirectData option,
 packets for nodes for which we do not have a meta connection with are also dropped.
 
 @cindex Forwarding
-@item Forwarding = <off|internal|kernel> (internal)
+@item Forwarding = <off|internal|kernel> (internal) [experimental]
 This option selects the way indirect packets are forwarded.
 
 @table @asis
index c734a0bbff68f6b4fc023c35ef061d53e6b677a5..d5bc9165804209608d30ced5bf589128e3b946ce 100644 (file)
@@ -224,7 +224,7 @@ static char *readline(FILE * fp, char *buf, size_t buflen) {
        newline = strchr(p, '\n');
 
        if(!newline)
-               return NULL;
+               return buf;
 
        *newline = '\0';        /* kill newline */
        if(newline > p && newline[-1] == '\r')  /* and carriage return if necessary */
@@ -238,7 +238,6 @@ static char *readline(FILE * fp, char *buf, size_t buflen) {
   starting at *base.
 */
 int read_config_file(splay_tree_t *config_tree, const char *fname) {
-       int err = -2;                           /* Parse error */
        FILE *fp;
        char buffer[MAX_STRING_SIZE];
        char *line;
index 80ab17c506aaa096da22d3af72657490589b10fb..940c239c985737669802aca300d80c34f78369af 100644 (file)
 #define ICMP_NET_UNREACH 0
 #endif
 
+#ifndef ICMP_NET_ANO
+#define ICMP_NET_ANO 9
+#endif
+
 #ifndef IP_MSS
 #define       IP_MSS          576
 #endif
index fee74f5ebc219b9399e6c141afac5eccfd2067c8..d98001d6a0c2569ad26358a0d43fd5f0f561eec2 100644 (file)
@@ -95,6 +95,7 @@ struct icmp6_hdr {
 #define ICMP6_DST_UNREACH_NOROUTE 0
 #define ICMP6_DST_UNREACH 1
 #define ICMP6_PACKET_TOO_BIG 2
+#define ICMP6_DST_UNREACH_ADMIN 1
 #define ICMP6_DST_UNREACH_ADDR 3
 #define ND_NEIGHBOR_SOLICIT 135
 #define ND_NEIGHBOR_ADVERT 136
index 23b3e7ca1316446689008184e5fdeaa4b5fdaf5f..0e5823641de349b1bb2321623be9820e0a37891c 100644 (file)
--- a/src/net.c
+++ b/src/net.c
@@ -270,6 +270,36 @@ int reload_configuration(void) {
 
        last_config_check = time(NULL);
 
+       /* If StrictSubnet is set, expire deleted Subnets and read new ones in */
+
+       if(strictsubnets) {
+               subnet_t *subnet;
+
+               for(node = subnet_tree->head; node; node = node->next) {
+                       subnet = node->data;
+                       subnet->expires = 1;
+               }
+
+               load_all_subnets();
+
+               for(node = subnet_tree->head; node; node = next) {
+                       next = node->next;
+                       subnet = node->data;
+                       if(subnet->expires == 1) {
+                               send_del_subnet(broadcast, subnet);
+                               if(subnet->owner->status.reachable)
+                                       subnet_update(subnet->owner, subnet, false);
+                               subnet_del(subnet->owner, subnet);
+                       } else if(subnet->expires == -1) {
+                               subnet->expires = 0;
+                       } else {
+                               send_add_subnet(broadcast, subnet);
+                               if(subnet->owner->status.reachable)
+                                       subnet_update(subnet->owner, subnet, true);
+                       }
+               }
+       }
+
        /* Try to make outgoing connections */
        
        try_outgoing_connections();
index 634e9e75d3447eca5a0bcd158b8f0984954f9f5b..cd97e301e3e8f85c30d21c0df5f2e69a3de960cb 100644 (file)
--- a/src/net.h
+++ b/src/net.h
@@ -144,6 +144,7 @@ extern void regenerate_key();
 extern void purge(void);
 extern void retry(void);
 extern int reload_configuration(void);
+extern void load_all_subnets();
 
 #ifndef HAVE_MINGW
 #define closesocket(s) close(s)
index c2ae6491407b28a4f3e413db77ecb79866fa78a9..593d8625b410a2ca87c0444ad86fd614adf336d6 100644 (file)
@@ -157,14 +157,14 @@ void regenerate_key() {
 /*
   Read Subnets from all host config files
 */
-static void load_all_subnets(void) {
+void load_all_subnets(void) {
        DIR *dir;
        struct dirent *ent;
        char *dname;
        char *fname;
        splay_tree_t *config_tree;
        config_t *cfg;
-       subnet_t *s;
+       subnet_t *s, *s2;
        node_t *n;
        bool result;
 
@@ -181,9 +181,6 @@ static void load_all_subnets(void) {
                        continue;
 
                n = lookup_node(ent->d_name);
-               if(n)
-                       continue;
-
                #ifdef _DIRENT_HAVE_D_TYPE
                //if(ent->d_type != DT_REG)
                //      continue;
@@ -196,15 +193,21 @@ static void load_all_subnets(void) {
                if(!result)
                        continue;
 
-               n = new_node();
-               n->name = xstrdup(ent->d_name);
-               node_add(n);
+               if(!n) {
+                       n = new_node();
+                       n->name = xstrdup(ent->d_name);
+                       node_add(n);
+               }
 
                for(cfg = lookup_config(config_tree, "Subnet"); cfg; cfg = lookup_config_next(config_tree, cfg)) {
                        if(!get_config_subnet(cfg, &s))
                                continue;
 
-                       subnet_add(n, s);
+                       if((s2 = lookup_subnet(n, s))) {
+                               s2->expires = -1;
+                       } else {
+                               subnet_add(n, s);
+                       }
                }
 
                exit_configuration(&config_tree);
@@ -262,6 +265,16 @@ bool setup_myself(void) {
                        && !get_config_string(lookup_config(myself->connection->config_tree, "Port"), &myport))
                myport = xstrdup("655");
 
+       if(!atoi(myport)) {
+               struct addrinfo *ai = str2addrinfo("localhost", myport, SOCK_DGRAM);
+               sockaddr_t sa;
+               if(!ai || !ai->ai_addr)
+                       return false;
+               free(myport);
+               memcpy(&sa, ai->ai_addr, ai->ai_addrlen);
+               sockaddr2str(&sa, NULL, &myport);
+       }
+
        /* Read in all the subnets specified in the host configuration file */
 
        cfg = lookup_config(myself->connection->config_tree, "Subnet");
index 2d8de9e8c1836c500160b6de084a776506063b0f..8ad2ce99ea94a118a0c3d85233c1183b0ae483ca 100644 (file)
@@ -102,8 +102,10 @@ void sockaddr2str(const sockaddr_t *sa, char **addrstr, char **portstr) {
        if(scopeid)
                *scopeid = '\0';                /* Descope. */
 
-       *addrstr = xstrdup(address);
-       *portstr = xstrdup(port);
+       if(addrstr)
+               *addrstr = xstrdup(address);
+       if(portstr)
+               *portstr = xstrdup(port);
 }
 
 char *sockaddr2hostname(const sockaddr_t *sa) {
index cf6b26f2d4ad3f915c6532c93cf421769309281e..8d4dfb939eb881824e3cdd96e739f4c5190a4aca 100644 (file)
@@ -401,7 +401,7 @@ static void send_everything(connection_t *c) {
 
 bool ack_h(connection_t *c, char *request) {
        char hisport[MAX_STRING_SIZE];
-       char *hisaddress, *dummy;
+       char *hisaddress;
        int weight, mtu;
        uint32_t options;
        node_t *n;
@@ -479,10 +479,9 @@ bool ack_h(connection_t *c, char *request) {
        c->edge = new_edge();
        c->edge->from = myself;
        c->edge->to = n;
-       sockaddr2str(&c->address, &hisaddress, &dummy);
+       sockaddr2str(&c->address, &hisaddress, NULL);
        c->edge->address = str2sockaddr(hisaddress, hisport);
        free(hisaddress);
-       free(dummy);
        c->edge->weight = (weight + c->estimated_weight) / 2;
        c->edge->connection = c;
        c->edge->options = c->options;
index f18bd268305a520cc3ba7c1d22e6aacf7fa2c15b..9897d0d7e260f602ad809ff595d48226ffe60c6b 100644 (file)
@@ -50,7 +50,10 @@ static const size_t ip6_size = sizeof(struct ip6_hdr);
 static const size_t icmp6_size = sizeof(struct icmp6_hdr);
 static const size_t ns_size = sizeof(struct nd_neighbor_solicit);
 static const size_t opt_size = sizeof(struct nd_opt_hdr);
-#define max(a, b) ((a) > (b) ? (a) : (b))
+
+#ifndef MAX
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
+#endif
 
 static struct event age_subnets_event;
 
@@ -412,10 +415,10 @@ static void route_ipv4_unicast(node_t *source, vpn_packet_t *packet) {
        if(directonly && subnet->owner != via)
                return route_ipv4_unreachable(source, packet, ICMP_DEST_UNREACH, ICMP_NET_ANO);
 
-       if(via && packet->len > max(via->mtu, 590) && via != myself) {
+       if(via && packet->len > MAX(via->mtu, 590) && via != myself) {
                ifdebug(TRAFFIC) logger(LOG_INFO, "Packet for %s (%s) length %d larger than MTU %d", subnet->owner->name, subnet->owner->hostname, packet->len, via->mtu);
                if(packet->data[20] & 0x40) {
-                       packet->len = max(via->mtu, 590);
+                       packet->len = MAX(via->mtu, 590);
                        route_ipv4_unreachable(source, packet, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED);
                } else {
                        fragment_ipv4_packet(via, packet);
@@ -563,9 +566,9 @@ static void route_ipv6_unicast(node_t *source, vpn_packet_t *packet) {
        if(directonly && subnet->owner != via)
                return route_ipv6_unreachable(source, packet, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADMIN);
 
-       if(via && packet->len > max(via->mtu, 1294) && via != myself) {
+       if(via && packet->len > MAX(via->mtu, 1294) && via != myself) {
                ifdebug(TRAFFIC) logger(LOG_INFO, "Packet for %s (%s) length %d larger than MTU %d", subnet->owner->name, subnet->owner->hostname, packet->len, via->mtu);
-               packet->len = max(via->mtu, 1294);
+               packet->len = MAX(via->mtu, 1294);
                route_ipv6_unreachable(source, packet, ICMP6_PACKET_TOO_BIG, 0);
                return;
        }
index df48f60eda8268cc989cb9591bf47b4c72076c8f..f22e6d58abfc0d36ee601519a999922cedf2612c 100644 (file)
@@ -64,6 +64,8 @@ typedef struct subnet_t {
 
 #define MAXNETSTR 64
 
+extern splay_tree_t *subnet_tree;
+
 extern int subnet_compare(const struct subnet_t *, const struct subnet_t *);
 extern subnet_t *new_subnet(void) __attribute__ ((__malloc__));
 extern void free_subnet(subnet_t *);