Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Trying to fix apple TUN issue.

  • Loading branch information...
commit 5b2b84662e59252c7e3d9115d378b9b46ee7b835 1 parent 5ddc35d
Caleb James DeLisle authored
View
49 interface/InterfaceController.h
@@ -21,34 +21,63 @@
#include <stdint.h>
#include <stdbool.h>
+enum InterfaceController_PeerState
+{
+ /** If state is UNAUTHENTICATED, the other node has not sent a single valid packet. */
+ InterfaceController_PeerState_UNAUTHENTICATED = 0,
+
+ /** In state == HANDSHAKE, a valid packet has been received but it could still be a replay. */
+ InterfaceController_PeerState_HANDSHAKE,
+
+ /** In state == ESTABLISHED, we know the node at the other end is authentic. */
+ InterfaceController_PeerState_ESTABLISHED,
+
+ /** If state == UNRESPONSIVE, the peer has not responded to pings in the required timeframe. */
+ InterfaceController_PeerState_UNRESPONSIVE
+};
+
struct InterfaceController
{
/**
* Add a new peer.
* Called from the network interface when it is asked to make a connection or it autoconnects.
+ * If the peer which is connected to becomes unresponsive, IC will *not* remove it but will
+ * set it's state to UNRESPONSIVE and it is the job of the caller to remove the peer by freeing
+ * the allocator which is provided with iface.
*
+ * If a peer is registered and it turns out to have the same cryptographic key as an existing
+ * peer, the existing one will be freed by the IC and the new one will take it's place.
+ * BEWARE: the interface allocator you provide here may be freed by this code!
+ *
+ * @param ic the interface controller.
* @param herPublicKey the public key of the foreign node, NULL if unknown.
- * @param password the password for authenticating with the other node if specified.
+ * @param password the password for authenticating with the other node or NULL if unspecified.
* @param requireAuth true if the other node must authenticate (incoming connection).
- * @param iface an interface which pipes messages to this peer.
- * @param ic the interface controller, a child of the memory allocator for this controller
- * will be used for the endpoint because we want to be able to free a single
- * endpoint without freeing the whole network interface but if the network interface
- * is freed, we would expect all of its children to deregister.
+ * @param iface an interface which pipes messages to/from this peer. The peer will be
+ * deregistered if this allocator is freed.
+ *
* @return 0 if all goes well.
- * InterfaceController_registerInterface_BAD_KEY if the key is not a valid cjdns key.
- * InterfaceController_registerInterface_OUT_OF_SPACE if no space to store the entry.
+ * InterfaceController_registerPeer_OUT_OF_SPACE if there is no space to store the peer.
+ * InterfaceController_registerPeer_BAD_KEY the provided herPublicKey is not valid.
+ * InterfaceController_registerPeer_INTERNAL unspecified error.
*/
- #define InterfaceController_registerPeer_OUT_OF_SPACE -1
+ #define InterfaceController_registerPeer_INTERNAL -3
#define InterfaceController_registerPeer_BAD_KEY -2
+ #define InterfaceController_registerPeer_OUT_OF_SPACE -1
int (* const registerPeer)(struct InterfaceController* ic,
uint8_t herPublicKey[32],
String* password,
bool requireAuth,
struct Interface* iface);
+
+ /** Get the current state of a registered interface. */
+ enum InterfaceController_PeerState (* const getPeerState)(struct Interface* iface);
};
+#define InterfaceController_getPeerState(ic, iface) \
+ ((ic)->getPeerState(iface))
+
#define InterfaceController_registerPeer(ic, herPublicKey, password, requireAuth, iface) \
- (ic)->registerPeer((ic), (herPublicKey), (password), (requireAuth), (iface))
+ ((ic)->registerPeer((ic), (herPublicKey), (password), (requireAuth), (iface)))
#endif
View
17 interface/MultiInterface.c
@@ -45,6 +45,9 @@ struct Peer
/** The multi-iface containing this peer. */
struct MultiInterface* multiIface;
+ /** The InterfaceController's structure which is used to detect unresponsive peers. */
+ struct InterfaceController_Peer* ifcPeer;
+
Identity
/** Variable size. */
@@ -150,6 +153,7 @@ static inline struct Peer* peerForKey(struct MultiInterface_pvt* mif,
return peer;
}
+/** Incoming from the network interface */
static uint8_t receiveMessage(struct Message* msg, struct Interface* external)
{
struct MultiInterface_pvt* mif =
@@ -163,7 +167,18 @@ static uint8_t receiveMessage(struct Message* msg, struct Interface* external)
// pop the key size and key
Message_shift(msg, -(mif->pub.keySize + 4));
- return p->internalIf.receiveMessage(msg, &p->internalIf);
+ // into the core.
+ uint8_t ret = p->internalIf.receiveMessage(msg, &p->internalIf);
+
+ enum InterfaceController_PeerState state =
+ InterfaceController_getPeerState(mif->ic, &p->internalIf);
+ if (state == InterfaceController_PeerState_UNAUTHENTICATED) {
+ // some random stray packet wandered in to the interface....
+ // This removes all of the state associated with the endpoint.
+ Allocator_free(p->internalIf.allocator);
+ }
+
+ return ret;
}
struct Interface* MultiInterface_ifaceForKey(struct MultiInterface* mIface, void* key)
View
7 interface/TUNInterface.c
@@ -48,7 +48,12 @@ static void handleEvent(void* vcontext)
}
msg->length = length;
- #ifdef Illumos
+ #ifdef OSX
+ // OSX tags the message with the AF type (AF_INET or AF_INET6) rather than the ethertype.
+ // pop it and scrap it then tag it the same as we do for Illumos.
+ TUNInterface_popMessageType(msg);
+ #endif
+ #if defined(Illumos) || defined(OSX)
// Illumos does not send packet info, it only supports ip4 and ip6 over tun.
uint16_t ethertype = ((msg->bytes[0] >> 4) == 6) ? Ethernet_TYPE_IP6 : Ethernet_TYPE_IP4;
TUNInterface_pushMessageType(msg, ethertype);
View
14 interface/UDPInterface.c
@@ -178,12 +178,20 @@ struct UDPInterface* UDPInterface_new(struct event_base* base,
context->socket = socket(addrFam, SOCK_DGRAM, 0);
if (context->socket == -1) {
- Except_raise(exHandler, UDPInterface_new_BIND_FAILED, "call to socket() failed.");
+ Except_raise(exHandler,
+ UDPInterface_new_BIND_FAILED,
+ "call to socket() failed [%s]",
+ Errno_getString());
}
if (bindAddr != NULL) {
if (bind(context->socket, (struct sockaddr*) &addr, context->addrLen)) {
- Except_raise(exHandler, UDPInterface_new_BIND_FAILED, "call to bind() failed.");
+ enum Errno err = Errno_get();
+ EVUTIL_CLOSESOCKET(context->socket);
+ Except_raise(exHandler,
+ UDPInterface_new_BIND_FAILED,
+ "call to bind() failed [%s]",
+ Errno_strerror(err));
}
}
@@ -192,7 +200,7 @@ struct UDPInterface* UDPInterface_new(struct event_base* base,
EVUTIL_CLOSESOCKET(context->socket);
Except_raise(exHandler, -1, "Failed to get socket name [%s]", Errno_strerror(err));
}
- Bits_memcpyConst(&context->boundPort_be, &((struct sockaddr_in*)&addr)->sin_port, 2);
+ Bits_memcpyConst(&context->pub.boundPort_be, &((struct sockaddr_in*)&addr)->sin_port, 2);
evutil_make_socket_nonblocking(context->socket);
View
3  interface/UDPInterface.h
@@ -24,6 +24,9 @@
struct UDPInterface
{
struct Interface generic;
+
+ /** Used for testing. */
+ uint16_t boundPort_be;
};
/**
View
3  interface/UDPInterface_pvt.h
@@ -53,9 +53,6 @@ struct UDPInterface_pvt
struct MultiInterface* multiIface;
- /** used for testing. */
- uint16_t boundPort_be;
-
Identity
};
View
7 interface/test/MultiInterface_test.c
@@ -62,6 +62,10 @@ static int registerPeer(struct InterfaceController* ic,
return 0;
}
+static enum InterfaceController_PeerState getPeerState(struct Interface* iface)
+{
+ return InterfaceController_PeerState_HANDSHAKE;
+}
int main()
{
@@ -71,7 +75,8 @@ int main()
// mock interface controller.
struct Context ctx = {
.ic = {
- .registerPeer = registerPeer
+ .registerPeer = registerPeer,
+ .getPeerState = getPeerState
}
};
View
9 interface/test/TUNInterface_ipv4_root_test.c
@@ -64,7 +64,10 @@ static uint8_t receiveMessageTUN(struct Message* msg, struct Interface* iface)
{
receivedMessageTUNCount++;
uint16_t ethertype = TUNInterface_popMessageType(msg);
- Assert_always(ethertype == Ethernet_TYPE_IP4);
+ if (ethertype != Ethernet_TYPE_IP4) {
+ printf("Spurious packet with ethertype [%u]\n", Endian_bigEndianToHost16(ethertype));
+ return 0;
+ }
struct Headers_IP4Header* header = (struct Headers_IP4Header*) msg->bytes;
@@ -113,10 +116,10 @@ int main(int argc, char** argv)
TUNConfigurator_addIp4Address(assignedInterfaceName, testAddrA, 30, logger, NULL);
struct TUNInterface* tun = TUNInterface_new(tunPtr, base, alloc);
- struct UDPInterface* udp = UDPInterface_new(base, "11.0.0.1:5000", alloc, NULL, logger, &ic);
+ struct UDPInterface* udp = UDPInterface_new(base, "0.0.0.0", alloc, NULL, logger, &ic);
struct sockaddr_in sin = { .sin_family = AF_INET };
- sin.sin_port = Endian_hostToBigEndian16(5000);
+ sin.sin_port = udp->boundPort_be;
Bits_memcpy(&sin.sin_addr, testAddrB, 4);
struct Message* msg;
View
11 interface/test/TUNInterface_ipv6_root_test.c
@@ -63,7 +63,10 @@ static uint8_t receiveMessageTUN(struct Message* msg, struct Interface* iface)
{
receivedMessageTUNCount++;
uint16_t ethertype = TUNInterface_popMessageType(msg);
- Assert_always(ethertype == Ethernet_TYPE_IP6);
+ if (ethertype != Ethernet_TYPE_IP6) {
+ printf("Spurious packet with ethertype [%u]\n", Endian_bigEndianToHost16(ethertype));
+ return 0;
+ }
struct Headers_IP6Header* header = (struct Headers_IP6Header*) msg->bytes;
@@ -83,7 +86,7 @@ static uint8_t receiveMessageTUN(struct Message* msg, struct Interface* iface)
static uint8_t receiveMessageUDP(struct Message* msg, struct Interface* iface)
{
if (!receivedMessageTUNCount) {
- // return 0;
+ return 0;
}
// Got the message, test successful.
exit(0);
@@ -112,10 +115,10 @@ int main(int argc, char** argv)
TUNConfigurator_addIp6Address(assignedInterfaceName, testAddrA, 126, logger, NULL);
struct TUNInterface* tun = TUNInterface_new(tunPtr, base, alloc);
- struct UDPInterface* udp = UDPInterface_new(base, "[fd00::1]:5000", alloc, NULL, logger, &ic);
+ struct UDPInterface* udp = UDPInterface_new(base, "[::]", alloc, NULL, logger, &ic);
struct sockaddr_in6 sin = { .sin6_family = AF_INET6 };
- sin.sin6_port = Endian_hostToBigEndian16(5000);
+ sin.sin6_port = udp->boundPort_be;
Bits_memcpy(&sin.sin6_addr, testAddrB, 16);
struct Message* msg;
View
2  interface/test/UDPInterface_communication_test.c
@@ -91,7 +91,7 @@ int main(int argc, char** argv)
struct sockaddr_in sin = { .sin_family = AF_INET };
- sin.sin_port = ((struct UDPInterface_pvt*) udpA)->boundPort_be;
+ sin.sin_port = udpA->boundPort_be;
uint8_t localHost[] = {127, 0, 0, 1};
Bits_memcpyConst(&sin.sin_addr, localHost, 4);
View
200 net/DefaultInterfaceController.c
@@ -27,11 +27,6 @@
#include <stddef.h> // offsetof
-
-#ifndef CJDNS_MAX_PEERS
- #error CJDNS_MAX_PEERS needs to be defined.
-#endif
-
/** After this number of milliseconds, a node will be regarded as unresponsive. */
#define UNRESPONSIVE_AFTER_MILLISECONDS 20000
@@ -43,59 +38,40 @@
/*--------------------Structs--------------------*/
-struct Endpoint
+struct IFCPeer
{
+ /** The interface which is registered with the switch. */
struct Interface switchIf;
+ /** The internal (wrapped by CryptoAuth) interface. */
struct Interface* cryptoAuthIf;
- /**
- * The internal interface, this is on the external side of the CryptoAuth.
- * This is wrapped by CryptoAuth and incoming packets from the CryptoAuth go to
- * receivedAfterCryptoAuth() then to the switch.
- */
- struct Interface internal;
-
/** The external (network side) interface. */
struct Interface* external;
/** The label for this endpoint, needed to ping the endpoint. */
uint64_t switchLabel;
+ /** Milliseconds since the epoch when the last *valid* message was received. */
+ uint64_t timeOfLastMessage;
+
/** The handle which can be used to look up this endpoint in the endpoint set. */
uint32_t handle;
- /** If state is UNAUTHENTICATED, the other node has not sent a single valid packet. */
- #define Endpoint_state_UNAUTHENTICATED 0
-
- /** In state == HANDSHAKE, a valid packet has been received but it could still be a replay . */
- #define Endpoint_state_HANDSHAKE 1
-
- /** In state == ESTABLISHED, we know the node at the other end is authentic. */
- #define Endpoint_state_ESTABLISHED 2
-
/**
- * one of Endpoint_state_UNAUTHENTICATED, Endpoint_state_HANDSHAKE or
- * Endpoint_state_ESTABLISHED.
- * If Endpoint_state_UNAUTHENTICATED, no permanent state will be kept.
- * During transition from Endpoint_state_HANDSHAKE to Endpoint_state_ESTABLISHED, a check
- * is done for a registeration of a node which is already registered in a different switch
- * slot, if there is one and the handshake completes, it will be moved.
+ * If InterfaceController_PeerState_UNAUTHENTICATED, no permanent state will be kept.
+ * During transition from HANDSHAKE to ESTABLISHED, a check is done for a registeration of a
+ * node which is already registered in a different switch slot, if there is one and the
+ * handshake completes, it will be moved.
*/
- int state;
-
- /**
- * The time of the last incoming message in milliseconds, used to clear out endpoints
- * if they are not responsive.
- */
- uint64_t timeOfLastMessage;
+ enum InterfaceController_PeerState state;
Identity
};
#define Map_NAME OfEndpointsByKey
#define Map_ENABLE_HANDLES
-#define Map_VALUE_TYPE struct Endpoint*
+#define Map_VALUE_TYPE struct IFCPeer*
#include "util/Map.h"
struct Context
@@ -103,7 +79,7 @@ struct Context
/** Public functions and fields for this ifcontroller. */
struct InterfaceController pub;
- /** Used to get an endpoint by its lookup key, endpoint.internal is entered into the map. */
+ /** Used to get an endpoint by its lookup key, endpoint->external is entered into the map. */
struct Map_OfEndpointsByKey endpointSet;
struct Allocator* const allocator;
@@ -118,7 +94,7 @@ struct Context
struct Log* const logger;
- struct event_base* const eventBase;
+ struct EventBase* const eventBase;
/** After this number of milliseconds, a neoghbor will be regarded as unresponsive. */
uint32_t unresponsiveAfterMilliseconds;
@@ -143,9 +119,9 @@ struct Context
//---------------//
-static inline struct Context* interfaceControllerForEndpoint(struct Endpoint* ep)
+static inline struct Context* ifcontrollerForPeer(struct IFCPeer* ep)
{
- return Identity_cast((struct Context*)ep->internal.senderContext);
+ return Identity_cast((struct Context*) ep->switchIf.senderContext);
}
static void onPingResponse(enum SwitchPinger_Result result,
@@ -158,9 +134,9 @@ static void onPingResponse(enum SwitchPinger_Result result,
if (SwitchPinger_Result_OK != result) {
return;
}
- struct Endpoint* ep = onResponseContext;
- Identity_check(ep);
- struct Context* ic = interfaceControllerForEndpoint(ep);
+ struct IFCPeer* ep = Identity_cast((struct IFCPeer*) onResponseContext);
+ struct Context* ic = ifcontrollerForPeer(ep);
+
struct Address addr;
Bits_memset(&addr, 0, sizeof(struct Address));
Bits_memcpyConst(addr.key, CryptoAuth_getHerPublicKey(ep->cryptoAuthIf), 32);
@@ -183,13 +159,13 @@ static void onPingResponse(enum SwitchPinger_Result result,
// Called from the pingInteral timeout.
static void pingCallback(void* vic)
{
- struct Context* ic = vic;
+ struct Context* ic = Identity_cast((struct Context*) vic);
uint64_t now = Time_currentTimeMilliseconds(ic->eventBase);
ic->pingCount++;
// scan for endpoints have not sent anything recently.
for (uint32_t i = 0; i < ic->endpointSet.count; i++) {
- struct Endpoint* ep = ic->endpointSet.values[i];
+ struct IFCPeer* ep = ic->endpointSet.values[i];
if (now > ep->timeOfLastMessage + ic->pingAfterMilliseconds) {
#ifdef Log_DEBUG
uint8_t key[56];
@@ -200,6 +176,7 @@ static void pingCallback(void* vic)
if (ic->pingCount % 8) {
continue;
}
+ ep->state = InterfaceController_PeerState_UNRESPONSIVE;
Log_debug(ic->logger, "Pinging unresponsive neighbor [%s.k].", key);
} else {
Log_debug(ic->logger, "Pinging lazy neighbor [%s].", key);
@@ -219,26 +196,21 @@ static void pingCallback(void* vic)
}
}
-static inline struct Endpoint* endpointForInternalInterface(struct Interface* iface)
-{
- return Identity_cast((struct Endpoint*) (((char*)iface) - offsetof(struct Endpoint, internal)));
-}
-
/** If there's already an endpoint with the same public key, merge the new one with the old one. */
-static void moveEndpointIfNeeded(struct Endpoint* ep, struct Context* ic)
+static void moveEndpointIfNeeded(struct IFCPeer* ep, struct Context* ic)
{
Log_debug(ic->logger, "Checking for old sessions to merge with.");
uint8_t* key = CryptoAuth_getHerPublicKey(ep->cryptoAuthIf);
for (uint32_t i = 0; i < ic->endpointSet.count; i++) {
- struct Endpoint* thisEp = ic->endpointSet.values[i];
+ struct IFCPeer* thisEp = ic->endpointSet.values[i];
uint8_t* thisKey = CryptoAuth_getHerPublicKey(thisEp->cryptoAuthIf);
if (thisEp != ep && !Bits_memcmp(thisKey, key, 32)) {
Log_info(ic->logger, "Moving endpoint to merge new session with old.");
ep->switchLabel = thisEp->switchLabel;
SwitchCore_swapInterfaces(&thisEp->switchIf, &ep->switchIf);
- thisEp->internal.allocator->free(thisEp->internal.allocator);
+ Allocator_free(thisEp->external->allocator);
return;
}
}
@@ -247,16 +219,15 @@ static void moveEndpointIfNeeded(struct Endpoint* ep, struct Context* ic)
// Incoming message which has passed through the cryptoauth and needs to be forwarded to the switch.
static uint8_t receivedAfterCryptoAuth(struct Message* msg, struct Interface* cryptoAuthIf)
{
- struct Endpoint* ep = cryptoAuthIf->receiverContext;
- Identity_check(ep);
- struct Context* ic = interfaceControllerForEndpoint(ep);
+ struct IFCPeer* ep = Identity_cast((struct IFCPeer*) cryptoAuthIf->receiverContext);
+ struct Context* ic = ifcontrollerForPeer(ep);
- if (ep->state != Endpoint_state_ESTABLISHED) {
+ if (ep->state < InterfaceController_PeerState_ESTABLISHED) {
if (CryptoAuth_getState(cryptoAuthIf) >= CryptoAuth_HANDSHAKE3) {
moveEndpointIfNeeded(ep, ic);
- ep->state = Endpoint_state_ESTABLISHED;
+ ep->state = InterfaceController_PeerState_ESTABLISHED;
} else {
- ep->state = Endpoint_state_HANDSHAKE;
+ ep->state = InterfaceController_PeerState_HANDSHAKE;
// prevent some kinds of nasty things which could be done with packet replay.
// This is checking the message switch header and will drop it unless the label
// directs it to *this* router.
@@ -273,7 +244,10 @@ static uint8_t receivedAfterCryptoAuth(struct Message* msg, struct Interface* cr
pingCallback(ic);
}
}
+ } else if (ep->state == InterfaceController_PeerState_UNRESPONSIVE) {
+ ep->state = InterfaceController_PeerState_ESTABLISHED;
}
+
ep->timeOfLastMessage = Time_currentTimeMilliseconds(ic->eventBase);
return ep->switchIf.receiveMessage(msg, &ep->switchIf);
@@ -282,10 +256,7 @@ static uint8_t receivedAfterCryptoAuth(struct Message* msg, struct Interface* cr
// This is directly called from SwitchCore, message is not encrypted.
static uint8_t sendFromSwitch(struct Message* msg, struct Interface* switchIf)
{
- struct Endpoint* ep = switchIf->senderContext;
- Identity_check(ep);
- Assert_true(ep->switchIf.senderContext == ep);
- Assert_true(ep->internal.sendMessage);
+ struct IFCPeer* ep = Identity_cast((struct IFCPeer*) switchIf);
// This sucks but cryptoauth trashes the content when it encrypts
// and we need to be capable of sending back a coherent error message.
@@ -298,7 +269,7 @@ static uint8_t sendFromSwitch(struct Message* msg, struct Interface* switchIf)
uint8_t ret = ep->cryptoAuthIf->sendMessage(msg, ep->cryptoAuthIf);
// If this node is unresponsive then return an error.
- struct Context* ic = interfaceControllerForEndpoint(ep);
+ struct Context* ic = ifcontrollerForPeer(ep);
uint64_t now = Time_currentTimeMilliseconds(ic->eventBase);
if (ret || now - ep->timeOfLastMessage > ic->unresponsiveAfterMilliseconds)
{
@@ -320,42 +291,15 @@ static uint8_t sendFromSwitch(struct Message* msg, struct Interface* switchIf)
static void closeInterface(void* vendpoint)
{
- struct Endpoint* toClose = Identity_cast((struct Endpoint*) vendpoint);
- struct Context* ic = interfaceControllerForEndpoint(toClose);
+ struct IFCPeer* toClose = Identity_cast((struct IFCPeer*) vendpoint);
+
+ struct Context* ic = ifcontrollerForPeer(toClose);
int index = Map_OfEndpointsByKey_indexForHandle(toClose->handle, &ic->endpointSet);
Assert_true(index >= 0);
Map_OfEndpointsByKey_remove(index, &ic->endpointSet);
}
-/**
- * Take a message from the switch (which has already been encrypted) and prepend the key.
- * Send the result on to the actual network level interface.
- */
-static uint8_t sendMessage(struct Message* message, struct Interface* iface)
-{
- struct Endpoint* ep = endpointForInternalInterface(iface);
- Assert_true(ep->external);
- return ep->external->sendMessage(message, ep->external);
-}
-
-static uint8_t receiveMessage(struct Message* msg, struct Interface* iface);
-
-/**
- * Add a new endpoint.
- * Called from the network interface when it is asked to make a connection or it autoconnects.
- *
- * @param key the ip/mac address to use for discriminating this endpoint.
- * @param herPublicKey the public key of the foreign node, NULL if unknown.
- * @param requireAuth if true then the other end must supply a valid password on connect.
- * @param password the password for authenticating to the other node or null if none.
- * @param externalInterface the network interface which is used to connect to this node.
- * @param ic the interface controller, a child of the memory allocator for this controller
- * will be used for the endpoint because we want to be able to free a single
- * endpoint without freeing the whole network interface but if the network interface
- * is freed, we would expect all of its children to deregister.
- * @return the newly inserted endpoint, NULL if there is no space to add one.
- */
static int registerPeer(struct InterfaceController* ifController,
uint8_t herPublicKey[32],
String* password,
@@ -372,57 +316,49 @@ static int registerPeer(struct InterfaceController* ifController,
}
}
- if (ic->endpointSet.count >= CJDNS_MAX_PEERS) {
- return InterfaceController_registerPeer_OUT_OF_SPACE;
- }
-
struct Allocator* epAllocator = externalInterface->allocator;
- struct Endpoint* ep = Allocator_calloc(epAllocator, sizeof(struct Endpoint), 1);
+ struct IFCPeer* ep = Allocator_calloc(epAllocator, sizeof(struct IFCPeer), 1);
+ ep->external = externalInterface;
int setIndex = Map_OfEndpointsByKey_put(&ep, &ic->endpointSet);
ep->handle = ic->endpointSet.handles[setIndex];
Identity_set(ep);
- epAllocator->onFree(closeInterface, ep, epAllocator);
-
-
- externalInterface->receiverContext = ep;
- externalInterface->receiveMessage = receiveMessage;
-
+ Allocator_onFree(epAllocator, closeInterface, ep);
// If the other end need not supply a valid password to connect
// we will set the connection state to HANDSHAKE because we don't
// want the connection to be trashed after the first invalid packet.
if (!requireAuth) {
- ep->state = Endpoint_state_HANDSHAKE;
+ ep->state = InterfaceController_PeerState_HANDSHAKE;
}
- ep->external = externalInterface;
-
- Bits_memcpyConst(&ep->internal, (&(struct Interface) {
- .senderContext = ic,
- .sendMessage = sendMessage,
- .allocator = epAllocator,
- .maxMessageLength = externalInterface->maxMessageLength
- }), sizeof(struct Interface));
+ ep->cryptoAuthIf =
+ CryptoAuth_wrapInterface(externalInterface, herPublicKey, requireAuth, true, ic->ca);
- struct Interface* authedIf =
- CryptoAuth_wrapInterface(&ep->internal, herPublicKey, requireAuth, true, ic->ca);
+ ep->cryptoAuthIf->receiveMessage = receivedAfterCryptoAuth;
+ ep->cryptoAuthIf->receiverContext = ep;
// Always use authType 1 until something else comes along, then we'll have to refactor.
if (password) {
- CryptoAuth_setAuth(password, 1, authedIf);
+ CryptoAuth_setAuth(password, 1, ep->cryptoAuthIf);
}
- ep->cryptoAuthIf = authedIf;
Bits_memcpyConst(&ep->switchIf, (&(struct Interface) {
.sendMessage = sendFromSwitch,
- .senderContext = ep,
+
+ // ifcontrollerForPeer uses this.
+ // sendFromSwitch relies on the fact that the
+ // switchIf is the same memory location as the Peer.
+ .senderContext = ic,
+
.allocator = epAllocator
}), sizeof(struct Interface));
- Assert_true(!SwitchCore_addInterface(&ep->switchIf, 0, &ep->switchLabel, ic->switchCore));
-
- authedIf->receiveMessage = receivedAfterCryptoAuth;
- authedIf->receiverContext = ep;
+ int ret = SwitchCore_addInterface(&ep->switchIf, 0, &ep->switchLabel, ic->switchCore);
+ if (ret) {
+ return (ret == SwitchCore_addInterface_OUT_OF_SPACE)
+ ? InterfaceController_registerPeer_OUT_OF_SPACE
+ : InterfaceController_registerPeer_INTERNAL;
+ }
// We want the node to immedietly be pinged but we don't want it to appear unresponsive because
// the pinger will only ping every (PING_INTERVAL * 8) so we set timeOfLastMessage to
@@ -448,19 +384,10 @@ static int registerPeer(struct InterfaceController* ifController,
return 0;
}
-// Get an incoming message from a network interface, doesn't matter what interface or what endpoint.
-static uint8_t receiveMessage(struct Message* msg, struct Interface* iface)
+static enum InterfaceController_PeerState getPeerState(struct Interface* iface)
{
- struct Endpoint* ep = Identity_cast((struct Endpoint*) iface->receiverContext);
- uint8_t out = ep->internal.receiveMessage(msg, &ep->internal);
-
- if (ep->state == Endpoint_state_UNAUTHENTICATED) {
- // some random stray packet wandered in to the interface....
- // This removes all of the state associated with the endpoint.
- ep->internal.allocator->free(ep->internal.allocator);
- }
-
- return out;
+ struct IFCPeer* p = Identity_cast((struct IFCPeer*) iface->receiverContext);
+ return p->state;
}
struct InterfaceController* DefaultInterfaceController_new(struct CryptoAuth* ca,
@@ -474,7 +401,8 @@ struct InterfaceController* DefaultInterfaceController_new(struct CryptoAuth* ca
struct Context* out = Allocator_malloc(allocator, sizeof(struct Context));
Bits_memcpyConst(out, (&(struct Context) {
.pub = {
- .registerPeer = registerPeer
+ .registerPeer = registerPeer,
+ .getPeerState = getPeerState
},
.endpointSet = {
.allocator = allocator
View
2  switch/SwitchCore.c
@@ -315,7 +315,7 @@ int SwitchCore_addInterface(struct Interface* iface,
}
if (ifIndex == NumberCompress_INTERFACES) {
- return -1;
+ return SwitchCore_addInterface_OUT_OF_SPACE;
}
struct SwitchInterface* newIf = &core->interfaces[ifIndex];
View
3  switch/SwitchCore.h
@@ -41,8 +41,9 @@ struct SwitchCore* SwitchCore_new(struct Log* logger, struct Allocator* allocato
* @param labelOut_be a buffer which will be filled with the label part for getting
* to the newly added node. It will be set to the big endian value.
* @param core the switchcore.
- * @return 0 on success, -1 if there are no more interface slots.
+ * @return 0 on success, SwitchCore_addInterface_OUT_OF_SPACE if there are no more interface slots.
*/
+#define SwitchCore_addInterface_OUT_OF_SPACE -1
int SwitchCore_addInterface(struct Interface* iface,
const uint64_t trust,
uint64_t* labelOut_be,
Please sign in to comment.
Something went wrong with that request. Please try again.