Guus Sliepen [Sat, 16 Dec 2017 21:38:48 +0000 (22:38 +0100)]
Don't use SOL_IP and SOL_IPV6.
These macros do not exist on all platforms, instead one should use
IPPROTO_IP and IPPROTO_IPV6. This fixes a bug on macOS where the
IPV6_V6ONLY flag would not be applied and could result in IPv4 sockets
not working.
Guus Sliepen [Mon, 14 Aug 2017 19:19:41 +0000 (21:19 +0200)]
Add a test for a constellation of three nodes.
In particular, test whether two nodes that have been introduced to each
other via a third node can still continue to communicate with each other
when the third node goes offline.
Guus Sliepen [Sun, 13 Aug 2017 21:08:56 +0000 (23:08 +0200)]
Test cornercases of MeshLink channels.
- Ensure we can open a channel before starting MeshLink.
- Check that opening channels to a peer that has unregistered its accept
callback will not result in the poll callback to be called with a non-
zero length.
Guus Sliepen [Sun, 13 Aug 2017 21:07:25 +0000 (23:07 +0200)]
Add utility functions to create paired MeshLink instances.
This also adds a start_meshlink_pair() function which starts the two instances
and waits for them to establish a connection with each other. A condition
variable is used to avoid having to poll.
Guus Sliepen [Sun, 13 Aug 2017 15:51:28 +0000 (17:51 +0200)]
Reset UTCP timers after a succesful key exchange.
The problem is that MeshLink does key exchange with peers on-demand. One
has to start a channel for key exchange to be initiated, but it also tries
to send the first SYN packet immediately. This will not work, and then it
has to wait for the retransmit timer to expire before it will try to send
the SYN again. Since the retransmit timer is increased exponentially, this
can potentially take a long time. So when key exchange is finished, we now
force a reset of the timers of all UTCP connections with the peer.
Guus Sliepen [Sun, 13 Aug 2017 13:06:51 +0000 (15:06 +0200)]
Convert sizeof foo to sizeof(foo).
While technically sizeof is an operator and doesn't need the parentheses
around expressions it operates on, except if they are type names, code
formatters don't seem to handle this very well.
Guus Sliepen [Sun, 13 Aug 2017 12:57:29 +0000 (14:57 +0200)]
Remove hack to wait for a valid key.
This was obviously only necessary because the missing retransmits of SYN
packets. Now, if a channel is opened before we have finished the key
exchange with the peer, UTCP will retry after a second.
Don't start with underscores, as those are reserved for system
libraries. Make sure all start with MESHLINK_, and that they appear at
the top of the file.
Guus Sliepen [Sun, 25 Jun 2017 14:32:15 +0000 (16:32 +0200)]
Fix processing of mixed ID and SPTPS data.
When making a connection with another peer, the ID message and the first
SPTPS data is sent using separate send() calls, but they can be merged
along the way to the other side. When receiving the ID message, we
accidentily discarded the rest of the received packet. Handle this
properly.
The problem was found to trigger much more often on Linux kernel 4.4 in
KVM.
Guus Sliepen [Fri, 11 Mar 2016 11:08:48 +0000 (12:08 +0100)]
Add meshlink_get_external_address() and meshlink_add_external_address().
These functions try to discover the local node's external address by
contacting the meshlink.io server. The get function just returns the
discovered address as a string, the add function adds it as an Address,
so it will end up in the list of addresses when calling
meshlink_export().
Guus Sliepen [Thu, 17 Dec 2015 17:44:21 +0000 (18:44 +0100)]
Use free_known_addresses() to free memory allocated by get_known_addresses().
We know what struct addrinfo looks like, but the standard says nothing about
how it is allocated. So we cannot trust freeaddrinfo() to work correctly on
the struct addrinfo list we allocated ourselves in get_known_addresses().
To make a distinction by allocations from the latter and from str2addrinfo(),
we keep two pointers (*ai and *aip) in struct outgoing, and use the freeing
function that is appropriate for each.
Guus Sliepen [Fri, 13 Nov 2015 08:50:45 +0000 (08:50 +0000)]
Fix race condition when calling meshlink_stop() immediately after meshlink_start().
The event loop didn't react to event_loop_stop() if it wasn't started yet
(because that is done in mesh->thread). The solution is to add a
event_loop_start() function that is to be called by meshlink_start().
Guus Sliepen [Fri, 6 Nov 2015 22:33:58 +0000 (23:33 +0100)]
Fix meshlink_stop() on Mac OS X.
Mac OS X doesn't like shutdown(SHUT_RDWR) on listening sockets, and also
doesn't allow reopening a listening socket right after closing the
previous one on the same port. So avoid the whole business of closing
and reopening sockets by stopping the event loop and then doing a dummy
connect() to ourself to ensure select() in the network thread returns
immediately.
Guus Sliepen [Mon, 26 Oct 2015 22:06:53 +0000 (23:06 +0100)]
Fix incorrect SPTPS session labels.
To prevent a MITM from being able to splice different SPTPS sessions
together, each session has a unique label. snprintf() was used to fill a
buffer with the label, however the buffer was not big enough for the whole
label. Linux made sure the last byte of the buffer was a NUL character,
Windows did not, resulting in the two unable to connect to each other.
Guus Sliepen [Thu, 15 Oct 2015 11:26:31 +0000 (13:26 +0200)]
Remove unused replay window and RTT/bandwidth estimation code.
The replay window handling is done by SPTPS. The replaywin member of node_t
was not used at all. Somehwat related, there was RTT and bandwidth
estimation code that didn't work anymore and is not used anyway.
Guus Sliepen [Tue, 13 Oct 2015 12:14:08 +0000 (14:14 +0200)]
Determine the local node's address(es) and add them to its host config file.
Use the "UDP connect() to an external IP address" trick to determine the
local node's addresses in a platform independent way, without sending any
actual packets. Do this at meshlink_open() time, so the application has
immediate access to them when calling meshlink_export().
Guus Sliepen [Tue, 13 Oct 2015 12:12:13 +0000 (14:12 +0200)]
Don't append duplicate entries to configuration files.
Automatically detected addresses are appended to host config files by
Catta. However, it doesn't check whether the address is already known.
Have append_config_file() check that it doesn't write duplicate entries.
Guus Sliepen [Fri, 9 Oct 2015 20:47:55 +0000 (22:47 +0200)]
Fix a memory leak when retrying outgoing connections.
When retry_outgoing_handler() calls setup_outgoing_connection(), it can
be that the old configuration is still in memory. So clean that up
before reading in new configuration data.
Guus Sliepen [Wed, 21 Jun 2017 20:57:34 +0000 (22:57 +0200)]
Ignore address hints for our local node.
Catta also sees itself, which causes MeshLink to add address hints for
its own node. That causes link-local addresses to be added. When calling
meshlink_invite(), the first link-local address would then be used for
the invitation URL, which is not desirable.
Guus Sliepen [Tue, 18 Nov 2014 21:03:12 +0000 (22:03 +0100)]
In case two nodes start a SPTPS session simultaneously, deterministically choose one to succeed.
This fixes the problem where two nodes send a REQ_KEY to each other
simultaneously, which causes both of them to drop their current state
and respond to the other's REQ_KEY with an ANS_KEY, which won't succeed
any more because both of them forgot that state.
Guus Sliepen [Fri, 7 Nov 2014 23:53:58 +0000 (23:53 +0000)]
test/channel: don't let both sides connect to each other simultaneously.
The channel test fails to work reliably when the two threads are started
exactly simultaneously and both sides try to connect to each other. Both
sides simultaneously initiate a end-to-end SPTPS connection by sending
the appropriate req_key request, but upon reception of each others
request they reset their own state, causing SPTPS packets from the old
and the new state to cross each other. A timeout will occur eventually,
causing one side to try to restart the SPTPS connection. Since the
timeouts are slightly randomized, this sometimes causes the channel test
to work, sometimes not.