}
end:
- event_add(&n->mtuevent, &(struct timeval){timeout, 0});
+ event_add(&n->mtuevent, &(struct timeval){timeout, rand() % 100000});
}
void send_mtu_probe(node_t *n) {
if(!n->status.waitingforkey)
send_req_key(n);
else if(n->last_req_key + 10 < time(NULL)) {
+ logger(DEBUG_ALWAYS, LOG_DEBUG, "No key from %s after 10 seconds, restarting SPTPS", n->name);
sptps_stop(&n->sptps);
n->status.waitingforkey = false;
send_req_key(n);
sockaddr_t *sa;
int sock;
+ sockaddr_t broadcast;
/* Overloaded use of priority field: -1 means local broadcast */
if(origpriority == -1 && n->prevedge) {
- sockaddr_t broadcast;
- broadcast.in.sin_family = AF_INET;
- broadcast.in.sin_addr.s_addr = -1;
- broadcast.in.sin_port = n->prevedge->address.in.sin_port;
+ sock = rand() % listen_sockets;
+ memset(&broadcast, 0, sizeof broadcast);
+ if(listen_socket[sock].sa.sa.sa_family == AF_INET6) {
+ broadcast.in6.sin6_family = AF_INET6;
+ broadcast.in6.sin6_addr.s6_addr[0x0] = 0xff;
+ broadcast.in6.sin6_addr.s6_addr[0x1] = 0x02;
+ broadcast.in6.sin6_addr.s6_addr[0xf] = 0x01;
+ broadcast.in6.sin6_port = n->prevedge->address.in.sin_port;
+ broadcast.in6.sin6_scope_id = listen_socket[sock].sa.in6.sin6_scope_id;
+ } else {
+ broadcast.in.sin_family = AF_INET;
+ broadcast.in.sin_addr.s_addr = -1;
+ broadcast.in.sin_port = n->prevedge->address.in.sin_port;
+ }
sa = &broadcast;
- sock = 0;
} else {
if(origpriority == -1)
origpriority = 0;
bool send_sptps_data(void *handle, uint8_t type, const char *data, size_t len) {
node_t *to = handle;
- if(type >= SPTPS_HANDSHAKE
- || ((myself->options | to->options) & OPTION_TCPONLY)
- || (type != PKT_PROBE && len > to->minmtu)) {
+ /* Send it via TCP if it is a handshake packet, TCPOnly is in use, or this packet is larger than the MTU. */
+
+ if(type >= SPTPS_HANDSHAKE || ((myself->options | to->options) & OPTION_TCPONLY) || (type != PKT_PROBE && len > to->minmtu)) {
char buf[len * 4 / 3 + 5];
b64encode(data, buf, len);
+ /* If no valid key is known yet, send the packets using ANS_KEY requests,
+ to ensure we get to learn the reflexive UDP address. */
if(!to->status.validkey)
return send_request(to->nexthop->connection, "%d %s %s %s -1 -1 -1 %d", ANS_KEY, myself->name, to->name, buf, myself->incompression);
else
- return send_request(to->nexthop->connection, "%d %s %s %d %s", REQ_KEY, myself->name, to->name, type >= SPTPS_HANDSHAKE ? REQ_SPTPS : REQ_PACKET, buf);
+ return send_request(to->nexthop->connection, "%d %s %s %d %s", REQ_KEY, myself->name, to->name, REQ_SPTPS, buf);
}
- /* Send the packet */
+ /* Otherwise, send the packet via UDP */
struct sockaddr *sa;
socklen_t sl;
node_t *from = handle;
if(type == SPTPS_HANDSHAKE) {
- from->status.validkey = true;
- from->status.waitingforkey = false;
- logger(DEBUG_META, LOG_INFO, "SPTPS key exchange with %s (%s) succesful", from->name, from->hostname);
+ if(!from->status.validkey) {
+ from->status.validkey = true;
+ from->status.waitingforkey = false;
+ logger(DEBUG_META, LOG_INFO, "SPTPS key exchange with %s (%s) succesful", from->name, from->hostname);
+ }
return true;
}