Expose the raw SPTPS send interface from net_packet.
[tinc] / src / protocol_key.c
index ebc46f3..93d84a3 100644 (file)
@@ -1,7 +1,7 @@
 /*
     protocol_key.c -- handle the meta-protocol, key exchange
     Copyright (C) 1999-2005 Ivo Timmermans,
-                  2000-2013 Guus Sliepen <guus@tinc-vpn.org>
+                  2000-2014 Guus Sliepen <guus@tinc-vpn.org>
 
     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
@@ -87,9 +87,13 @@ bool key_changed_h(connection_t *c, const char *request) {
        return true;
 }
 
-static bool send_initial_sptps_data(void *handle, uint8_t type, const char *data, size_t len) {
+static bool send_sptps_data_myself(void *handle, uint8_t type, const void *data, size_t len) {
+       return send_sptps_data(handle, myself, type, data, len);
+}
+
+static bool send_initial_sptps_data(void *handle, uint8_t type, const void *data, size_t len) {
        node_t *to = handle;
-       to->sptps.send_data = send_sptps_data;
+       to->sptps.send_data = send_sptps_data_myself;
        char buf[len * 4 / 3 + 5];
        b64encode(data, buf, len);
        return send_request(to->nexthop->connection, "%d %s %s %d %s", REQ_KEY, myself->name, to->name, REQ_KEY, buf);
@@ -176,8 +180,9 @@ static bool req_key_ext_h(connection_t *c, const char *request, node_t *from, in
                        from->status.validkey = false;
                        from->status.waitingforkey = true;
                        from->last_req_key = now.tv_sec;
-                       sptps_start(&from->sptps, from, false, true, myself->connection->ecdsa, from->ecdsa, label, sizeof label, send_sptps_data, receive_sptps_record);
+                       sptps_start(&from->sptps, from, false, true, myself->connection->ecdsa, from->ecdsa, label, sizeof label, send_sptps_data_myself, receive_sptps_record);
                        sptps_receive_data(&from->sptps, buf, len);
+                       send_mtu_info(myself, from, MTU);
                        return true;
                }
 
@@ -194,6 +199,7 @@ static bool req_key_ext_h(connection_t *c, const char *request, node_t *from, in
                                return true;
                        }
                        sptps_receive_data(&from->sptps, buf, len);
+                       send_mtu_info(myself, from, MTU);
                        return true;
                }
 
@@ -236,6 +242,13 @@ bool req_key_h(connection_t *c, const char *request) {
                return true;
        }
 
+       /* If this is a SPTPS packet, see if sending UDP info helps.
+          Note that we only do this if we're the destination or the static relay;
+          otherwise every hop would initiate its own UDP info message, resulting in elevated chatter. */
+
+       if(experimental && (reqno == REQ_KEY || reqno == REQ_SPTPS) && to->via == myself)
+               send_udp_info(myself, from);
+
        /* Check if this key request is for us */
 
        if(to == myself) {                      /* Yes */
@@ -266,6 +279,9 @@ bool send_ans_key(node_t *to) {
        if(to->status.sptps)
                abort();
 
+#ifdef DISABLE_LEGACY
+       return false;
+#else
        size_t keylen = myself->incipher ? cipher_keylength(myself->incipher) : 1;
        char key[keylen * 2 + 1];
 
@@ -300,12 +316,15 @@ bool send_ans_key(node_t *to) {
        to->received = 0;
        if(replaywin) memset(to->late, 0, replaywin);
 
+       to->status.validkey_in = true;
+
        return send_request(to->nexthop->connection, "%d %s %s %s %d %d %d %d", ANS_KEY,
                                                myself->name, to->name, key,
                                                cipher_get_nid(to->incipher),
                                                digest_get_nid(to->indigest),
                                                (int)digest_length(to->indigest),
                                                to->incompression);
+#endif
 }
 
 bool ans_key_h(connection_t *c, const char *request) {
@@ -371,9 +390,11 @@ bool ans_key_h(connection_t *c, const char *request) {
                return send_request(to->nexthop->connection, "%s", request);
        }
 
+#ifndef DISABLE_LEGACY
        /* Don't use key material until every check has passed. */
        cipher_close(from->outcipher);
        digest_close(from->outdigest);
+#endif
        from->status.validkey = false;
 
        if(compression < 0 || compression > 11) {
@@ -398,16 +419,17 @@ bool ans_key_h(connection_t *c, const char *request) {
                                sockaddr_t sa = str2sockaddr(address, port);
                                update_node_udp(from, &sa);
                        }
-
-                       /* Don't send probes if we can't send UDP packets directly to that node.
-                          TODO: the indirect (via) condition can change at any time as edges are added and removed, so this should probably be moved to graph.c. */
-                       if((from->via == myself || from->via == from) && from->options & OPTION_PMTU_DISCOVERY && !(from->options & OPTION_TCPONLY))
-                               send_mtu_probe(from);
                }
 
+               send_mtu_info(myself, from, MTU);
+
                return true;
        }
 
+#ifdef DISABLE_LEGACY
+       logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses legacy protocol!", from->name, from->hostname);
+       return false;
+#else
        /* Check and lookup cipher and digest algorithms */
 
        if(cipher) {
@@ -458,8 +480,6 @@ bool ans_key_h(connection_t *c, const char *request) {
                update_node_udp(from, &sa);
        }
 
-       if(from->options & OPTION_PMTU_DISCOVERY && !(from->options & OPTION_TCPONLY))
-               send_mtu_probe(from);
-
        return true;
+#endif
 }