summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Ierymenko <adam.ierymenko@gmail.com>2015-09-23 13:49:56 -0700
committerAdam Ierymenko <adam.ierymenko@gmail.com>2015-09-23 13:49:56 -0700
commit367ffde00cf6eecbca0f9fff391dcaf7faf72c6e (patch)
treea3e345de1a0a5998ca7eec6fe9e2ff2283da6c80
parent4464fa5d392dd930bf847c2dc1c5886398e5d8dd (diff)
downloadinfinitytier-367ffde00cf6eecbca0f9fff391dcaf7faf72c6e.tar.gz
infinitytier-367ffde00cf6eecbca0f9fff391dcaf7faf72c6e.zip
Plumb through localInterfaceId to track local interfaces corresponding with remote addresses.
-rw-r--r--include/ZeroTierOne.h88
-rw-r--r--node/IncomingPacket.cpp58
-rw-r--r--node/IncomingPacket.hpp5
-rw-r--r--node/Node.cpp8
-rw-r--r--node/Node.hpp5
-rw-r--r--node/Peer.cpp21
-rw-r--r--node/Peer.hpp5
-rw-r--r--node/RemotePath.hpp9
-rw-r--r--node/Switch.cpp27
-rw-r--r--node/Switch.hpp14
-rw-r--r--node/Topology.cpp2
-rw-r--r--service/OneService.cpp6
12 files changed, 155 insertions, 93 deletions
diff --git a/include/ZeroTierOne.h b/include/ZeroTierOne.h
index b8d14c5f..fd0b0d24 100644
--- a/include/ZeroTierOne.h
+++ b/include/ZeroTierOne.h
@@ -656,7 +656,12 @@ typedef void ZT1_Node;
* on failure, and this results in the network being placed into the
* PORT_ERROR state.
*/
-typedef int (*ZT1_VirtualNetworkConfigFunction)(ZT1_Node *,void *,uint64_t,enum ZT1_VirtualNetworkConfigOperation,const ZT1_VirtualNetworkConfig *);
+typedef int (*ZT1_VirtualNetworkConfigFunction)(
+ ZT1_Node *,
+ void *,
+ uint64_t,
+ enum ZT1_VirtualNetworkConfigOperation,
+ const ZT1_VirtualNetworkConfig *);
/**
* Function to send a frame out to a virtual network port
@@ -665,7 +670,16 @@ typedef int (*ZT1_VirtualNetworkConfigFunction)(ZT1_Node *,void *,uint64_t,enum
* (5) destination MAC, (6) ethertype, (7) VLAN ID, (8) frame data,
* (9) frame length.
*/
-typedef void (*ZT1_VirtualNetworkFrameFunction)(ZT1_Node *,void *,uint64_t,uint64_t,uint64_t,unsigned int,unsigned int,const void *,unsigned int);
+typedef void (*ZT1_VirtualNetworkFrameFunction)(
+ ZT1_Node *,
+ void *,
+ uint64_t,
+ uint64_t,
+ uint64_t,
+ unsigned int,
+ unsigned int,
+ const void *,
+ unsigned int);
/**
* Callback for events
@@ -676,7 +690,11 @@ typedef void (*ZT1_VirtualNetworkFrameFunction)(ZT1_Node *,void *,uint64_t,uint6
* whether it is present at all) is event type dependent. See the comments
* in the definition of ZT1_Event.
*/
-typedef void (*ZT1_EventCallback)(ZT1_Node *,void *,enum ZT1_Event,const void *);
+typedef void (*ZT1_EventCallback)(
+ ZT1_Node *,
+ void *,
+ enum ZT1_Event,
+ const void *);
/**
* Function to get an object from the data store
@@ -698,7 +716,14 @@ typedef void (*ZT1_EventCallback)(ZT1_Node *,void *,enum ZT1_Event,const void *)
* read. The caller may call the function multiple times to read the whole
* object.
*/
-typedef long (*ZT1_DataStoreGetFunction)(ZT1_Node *,void *,const char *,void *,unsigned long,unsigned long,unsigned long *);
+typedef long (*ZT1_DataStoreGetFunction)(
+ ZT1_Node *,
+ void *,
+ const char *,
+ void *,
+ unsigned long,
+ unsigned long,
+ unsigned long *);
/**
* Function to store an object in the data store
@@ -716,19 +741,40 @@ typedef long (*ZT1_DataStoreGetFunction)(ZT1_Node *,void *,const char *,void *,u
* If the data pointer is null, this must be interpreted as a delete
* operation.
*/
-typedef int (*ZT1_DataStorePutFunction)(ZT1_Node *,void *,const char *,const void *,unsigned long,int);
+typedef int (*ZT1_DataStorePutFunction)(
+ ZT1_Node *,
+ void *,
+ const char *,
+ const void *,
+ unsigned long,
+ int);
/**
* Function to send a ZeroTier packet out over the wire
*
- * Parameters: (1) node, (2) user ptr, (3) address, (4) packet data,
- * (5) packet data length.
+ * Parameters:
+ * (1) Node
+ * (2) User pointer
+ * (3) Local interface ID, -1==unspcified/random
+ * (4) Remote address
+ * (5) Packet data
+ * (6) Packet length
+ *
+ * If you have only one local interface it is fine to ignore the local
+ * interface ID field. This is used to support different local interface
+ * endpoints and differentiation between them.
*
* The function must return zero on success and may return any error code
* on failure. Note that success does not (of course) guarantee packet
* delivery. It only means that the packet appears to have been sent.
*/
-typedef int (*ZT1_WirePacketSendFunction)(ZT1_Node *,void *,const struct sockaddr_storage *,const void *,unsigned int);
+typedef int (*ZT1_WirePacketSendFunction)(
+ ZT1_Node *, /* Node */
+ void *, /* User ptr */
+ int, /* Local interface ID, -1 for unspecified/random */
+ const struct sockaddr_storage *, /* Remote address */
+ const void *, /* Packet data */
+ unsigned int); /* Packet length */
/****************************************************************************/
/* C Node API */
@@ -747,7 +793,7 @@ typedef int (*ZT1_WirePacketSendFunction)(ZT1_Node *,void *,const struct sockadd
* @param dataStorePutFunction Function called to put objects in persistent storage
* @param virtualNetworkConfigFunction Function to be called when virtual LANs are created, deleted, or their config parameters change
* @param eventCallback Function to receive status updates and non-fatal error notices
- * @param overrideRootTopology If not NULL, must contain string-serialize root topology (for testing, default: NULL)
+ * @param overrideRootTopology Alternative root server topology or NULL for default (mostly for test/debug use)
* @return OK (0) or error code if a fatal error condition has occurred
*/
enum ZT1_ResultCode ZT1_Node_new(
@@ -760,11 +806,7 @@ enum ZT1_ResultCode ZT1_Node_new(
ZT1_VirtualNetworkFrameFunction virtualNetworkFrameFunction,
ZT1_VirtualNetworkConfigFunction virtualNetworkConfigFunction,
ZT1_EventCallback eventCallback,
- const char *overrideRootTopology
-#ifdef __cplusplus
- = (const char *)0
-#endif
- );
+ const char *overrideRootTopology);
/**
* Delete a node and free all resources it consumes
@@ -781,6 +823,7 @@ void ZT1_Node_delete(ZT1_Node *node);
*
* @param node Node instance
* @param now Current clock in milliseconds
+ * @param localInterfaceId Local interface ID on which packet was received (use 0 if only one interface or unsure)
* @param remoteAddress Origin of packet
* @param packetData Packet data
* @param packetLength Packet length
@@ -790,6 +833,7 @@ void ZT1_Node_delete(ZT1_Node *node);
enum ZT1_ResultCode ZT1_Node_processWirePacket(
ZT1_Node *node,
uint64_t now,
+ const int localInterfaceId,
const struct sockaddr_storage *remoteAddress,
const void *packetData,
unsigned int packetLength,
@@ -882,14 +926,10 @@ enum ZT1_ResultCode ZT1_Node_leave(ZT1_Node *node,uint64_t nwid);
* @param node Node instance
* @param nwid 64-bit network ID
* @param multicastGroup Ethernet multicast or broadcast MAC (least significant 48 bits)
- * @param multicastAdi Multicast ADI (least significant 32 bits only, default: 0)
+ * @param multicastAdi Multicast ADI (least significant 32 bits only, use 0 if not needed)
* @return OK (0) or error code if a fatal error condition has occurred
*/
-enum ZT1_ResultCode ZT1_Node_multicastSubscribe(ZT1_Node *node,uint64_t nwid,uint64_t multicastGroup,unsigned long multicastAdi
-#ifdef __cplusplus
- = 0
-#endif
- );
+enum ZT1_ResultCode ZT1_Node_multicastSubscribe(ZT1_Node *node,uint64_t nwid,uint64_t multicastGroup,unsigned long multicastAdi);
/**
* Unsubscribe from an Ethernet multicast group (or all groups)
@@ -902,14 +942,10 @@ enum ZT1_ResultCode ZT1_Node_multicastSubscribe(ZT1_Node *node,uint64_t nwid,uin
* @param node Node instance
* @param nwid 64-bit network ID
* @param multicastGroup Ethernet multicast or broadcast MAC (least significant 48 bits)
- * @param multicastAdi Multicast ADI (least significant 32 bits only, default: 0)
+ * @param multicastAdi Multicast ADI (least significant 32 bits only, use 0 if not needed)
* @return OK (0) or error code if a fatal error condition has occurred
*/
-enum ZT1_ResultCode ZT1_Node_multicastUnsubscribe(ZT1_Node *node,uint64_t nwid,uint64_t multicastGroup,unsigned long multicastAdi
-#ifdef __cplusplus
- = 0
-#endif
- );
+enum ZT1_ResultCode ZT1_Node_multicastUnsubscribe(ZT1_Node *node,uint64_t nwid,uint64_t multicastGroup,unsigned long multicastAdi);
/**
* Get this node's 40-bit ZeroTier address
diff --git a/node/IncomingPacket.cpp b/node/IncomingPacket.cpp
index fc79270b..e4861af7 100644
--- a/node/IncomingPacket.cpp
+++ b/node/IncomingPacket.cpp
@@ -69,7 +69,7 @@ bool IncomingPacket::tryDecode(const RuntimeEnvironment *RR)
switch(verb()) {
//case Packet::VERB_NOP:
default: // ignore unknown verbs, but if they pass auth check they are "received"
- peer->received(RR,_remoteAddress,hops(),packetId(),verb(),0,Packet::VERB_NOP);
+ peer->received(RR,_localInterfaceId,_remoteAddress,hops(),packetId(),verb(),0,Packet::VERB_NOP);
return true;
case Packet::VERB_HELLO: return _doHELLO(RR);
case Packet::VERB_ERROR: return _doERROR(RR,peer);
@@ -144,7 +144,7 @@ bool IncomingPacket::_doERROR(const RuntimeEnvironment *RR,const SharedPtr<Peer>
Packet outp(peer->address(),RR->identity.address(),Packet::VERB_NETWORK_MEMBERSHIP_CERTIFICATE);
nconf->com().serialize(outp);
outp.armor(peer->key(),true);
- RR->node->putPacket(_remoteAddress,outp.data(),outp.size());
+ RR->node->putPacket(_localInterfaceId,_remoteAddress,outp.data(),outp.size());
}
}
} break;
@@ -165,7 +165,7 @@ bool IncomingPacket::_doERROR(const RuntimeEnvironment *RR,const SharedPtr<Peer>
default: break;
}
- peer->received(RR,_remoteAddress,hops(),packetId(),Packet::VERB_ERROR,inRePacketId,inReVerb);
+ peer->received(RR,_localInterfaceId,_remoteAddress,hops(),packetId(),Packet::VERB_ERROR,inRePacketId,inReVerb);
} catch (std::exception &ex) {
TRACE("dropped ERROR from %s(%s): unexpected exception: %s",source().toString().c_str(),_remoteAddress.toString().c_str(),ex.what());
} catch ( ... ) {
@@ -231,7 +231,7 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR)
outp.append(packetId());
outp.append((unsigned char)Packet::ERROR_IDENTITY_COLLISION);
outp.armor(key,true);
- RR->node->putPacket(_remoteAddress,outp.data(),outp.size());
+ RR->node->putPacket(_localInterfaceId,_remoteAddress,outp.data(),outp.size());
} else {
RR->node->postEvent(ZT1_EVENT_AUTHENTICATION_FAILURE,(const void *)&_remoteAddress);
TRACE("rejected HELLO from %s(%s): packet failed authentication",id.address().toString().c_str(),_remoteAddress.toString().c_str());
@@ -278,7 +278,7 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR)
// VALID -- continues here
- peer->received(RR,_remoteAddress,hops(),packetId(),Packet::VERB_HELLO,0,Packet::VERB_NOP);
+ peer->received(RR,_localInterfaceId,_remoteAddress,hops(),packetId(),Packet::VERB_HELLO,0,Packet::VERB_NOP);
peer->setRemoteVersion(protoVersion,vMajor,vMinor,vRevision);
bool trusted = false;
@@ -316,7 +316,7 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR)
}
outp.armor(peer->key(),true);
- RR->node->putPacket(_remoteAddress,outp.data(),outp.size());
+ RR->node->putPacket(_localInterfaceId,_remoteAddress,outp.data(),outp.size());
} catch (std::exception &ex) {
TRACE("dropped HELLO from %s(%s): %s",source().toString().c_str(),_remoteAddress.toString().c_str(),ex.what());
} catch ( ... ) {
@@ -436,7 +436,7 @@ bool IncomingPacket::_doOK(const RuntimeEnvironment *RR,const SharedPtr<Peer> &p
default: break;
}
- peer->received(RR,_remoteAddress,hops(),packetId(),Packet::VERB_OK,inRePacketId,inReVerb);
+ peer->received(RR,_localInterfaceId,_remoteAddress,hops(),packetId(),Packet::VERB_OK,inRePacketId,inReVerb);
} catch (std::exception &ex) {
TRACE("dropped OK from %s(%s): unexpected exception: %s",source().toString().c_str(),_remoteAddress.toString().c_str(),ex.what());
} catch ( ... ) {
@@ -456,7 +456,7 @@ bool IncomingPacket::_doWHOIS(const RuntimeEnvironment *RR,const SharedPtr<Peer>
outp.append(packetId());
queried->identity().serialize(outp,false);
outp.armor(peer->key(),true);
- RR->node->putPacket(_remoteAddress,outp.data(),outp.size());
+ RR->node->putPacket(_localInterfaceId,_remoteAddress,outp.data(),outp.size());
} else {
Packet outp(peer->address(),RR->identity.address(),Packet::VERB_ERROR);
outp.append((unsigned char)Packet::VERB_WHOIS);
@@ -464,12 +464,12 @@ bool IncomingPacket::_doWHOIS(const RuntimeEnvironment *RR,const SharedPtr<Peer>
outp.append((unsigned char)Packet::ERROR_OBJ_NOT_FOUND);
outp.append(payload(),ZT_ADDRESS_LENGTH);
outp.armor(peer->key(),true);
- RR->node->putPacket(_remoteAddress,outp.data(),outp.size());
+ RR->node->putPacket(_localInterfaceId,_remoteAddress,outp.data(),outp.size());
}
} else {
TRACE("dropped WHOIS from %s(%s): missing or invalid address",source().toString().c_str(),_remoteAddress.toString().c_str());
}
- peer->received(RR,_remoteAddress,hops(),packetId(),Packet::VERB_WHOIS,0,Packet::VERB_NOP);
+ peer->received(RR,_localInterfaceId,_remoteAddress,hops(),packetId(),Packet::VERB_WHOIS,0,Packet::VERB_NOP);
} catch ( ... ) {
TRACE("dropped WHOIS from %s(%s): unexpected exception",source().toString().c_str(),_remoteAddress.toString().c_str());
}
@@ -487,8 +487,8 @@ bool IncomingPacket::_doRENDEZVOUS(const RuntimeEnvironment *RR,const SharedPtr<
if ((port > 0)&&((addrlen == 4)||(addrlen == 16))) {
InetAddress atAddr(field(ZT_PROTO_VERB_RENDEZVOUS_IDX_ADDRESS,addrlen),addrlen,port);
TRACE("RENDEZVOUS from %s says %s might be at %s, starting NAT-t",peer->address().toString().c_str(),with.toString().c_str(),atAddr.toString().c_str());
- peer->received(RR,_remoteAddress,hops(),packetId(),Packet::VERB_RENDEZVOUS,0,Packet::VERB_NOP);
- RR->sw->rendezvous(withPeer,atAddr);
+ peer->received(RR,_localInterfaceId,_remoteAddress,hops(),packetId(),Packet::VERB_RENDEZVOUS,0,Packet::VERB_NOP);
+ RR->sw->rendezvous(withPeer,_localInterfaceId,atAddr);
} else {
TRACE("dropped corrupt RENDEZVOUS from %s(%s) (bad address or port)",peer->address().toString().c_str(),_remoteAddress.toString().c_str());
}
@@ -525,7 +525,7 @@ bool IncomingPacket::_doFRAME(const RuntimeEnvironment *RR,const SharedPtr<Peer>
RR->node->putFrame(network->id(),MAC(peer->address(),network->id()),network->mac(),etherType,0,field(ZT_PROTO_VERB_FRAME_IDX_PAYLOAD,payloadLen),payloadLen);
}
- peer->received(RR,_remoteAddress,hops(),packetId(),Packet::VERB_FRAME,0,Packet::VERB_NOP);
+ peer->received(RR,_localInterfaceId,_remoteAddress,hops(),packetId(),Packet::VERB_FRAME,0,Packet::VERB_NOP);
} else {
TRACE("dropped FRAME from %s(%s): we are not connected to network %.16llx",source().toString().c_str(),_remoteAddress.toString().c_str(),at<uint64_t>(ZT_PROTO_VERB_FRAME_IDX_NETWORK_ID));
}
@@ -602,7 +602,7 @@ bool IncomingPacket::_doEXT_FRAME(const RuntimeEnvironment *RR,const SharedPtr<P
RR->node->putFrame(network->id(),from,to,etherType,0,field(comLen + ZT_PROTO_VERB_EXT_FRAME_IDX_PAYLOAD,payloadLen),payloadLen);
}
- peer->received(RR,_remoteAddress,hops(),packetId(),Packet::VERB_EXT_FRAME,0,Packet::VERB_NOP);
+ peer->received(RR,_localInterfaceId,_remoteAddress,hops(),packetId(),Packet::VERB_EXT_FRAME,0,Packet::VERB_NOP);
} else {
TRACE("dropped EXT_FRAME from %s(%s): we are not connected to network %.16llx",source().toString().c_str(),_remoteAddress.toString().c_str(),at<uint64_t>(ZT_PROTO_VERB_FRAME_IDX_NETWORK_ID));
}
@@ -623,7 +623,7 @@ bool IncomingPacket::_doMULTICAST_LIKE(const RuntimeEnvironment *RR,const Shared
for(unsigned int ptr=ZT_PACKET_IDX_PAYLOAD;ptr<size();ptr+=18)
RR->mc->add(now,at<uint64_t>(ptr),MulticastGroup(MAC(field(ptr + 8,6),6),at<uint32_t>(ptr + 14)),peer->address());
- peer->received(RR,_remoteAddress,hops(),packetId(),Packet::VERB_MULTICAST_LIKE,0,Packet::VERB_NOP);
+ peer->received(RR,_localInterfaceId,_remoteAddress,hops(),packetId(),Packet::VERB_MULTICAST_LIKE,0,Packet::VERB_NOP);
} catch (std::exception &ex) {
TRACE("dropped MULTICAST_LIKE from %s(%s): unexpected exception: %s",source().toString().c_str(),_remoteAddress.toString().c_str(),ex.what());
} catch ( ... ) {
@@ -647,7 +647,7 @@ bool IncomingPacket::_doNETWORK_MEMBERSHIP_CERTIFICATE(const RuntimeEnvironment
}
}
- peer->received(RR,_remoteAddress,hops(),packetId(),Packet::VERB_NETWORK_MEMBERSHIP_CERTIFICATE,0,Packet::VERB_NOP);
+ peer->received(RR,_localInterfaceId,_remoteAddress,hops(),packetId(),Packet::VERB_NETWORK_MEMBERSHIP_CERTIFICATE,0,Packet::VERB_NOP);
} catch (std::exception &ex) {
TRACE("dropped NETWORK_MEMBERSHIP_CERTIFICATE from %s(%s): unexpected exception: %s",source().toString().c_str(),_remoteAddress.toString().c_str(),ex.what());
} catch ( ... ) {
@@ -666,7 +666,7 @@ bool IncomingPacket::_doNETWORK_CONFIG_REQUEST(const RuntimeEnvironment *RR,cons
const unsigned int h = hops();
const uint64_t pid = packetId();
- peer->received(RR,_remoteAddress,h,pid,Packet::VERB_NETWORK_CONFIG_REQUEST,0,Packet::VERB_NOP);
+ peer->received(RR,_localInterfaceId,_remoteAddress,h,pid,Packet::VERB_NETWORK_CONFIG_REQUEST,0,Packet::VERB_NOP);
if (RR->localNetworkController) {
Dictionary netconf;
@@ -688,7 +688,7 @@ bool IncomingPacket::_doNETWORK_CONFIG_REQUEST(const RuntimeEnvironment *RR,cons
if (outp.size() > ZT_PROTO_MAX_PACKET_LENGTH) {
TRACE("NETWORK_CONFIG_REQUEST failed: internal error: netconf size %u is too large",(unsigned int)netconfStr.length());
} else {
- RR->node->putPacket(_remoteAddress,outp.data(),outp.size());
+ RR->node->putPacket(_localInterfaceId,_remoteAddress,outp.data(),outp.size());
}
}
} break;
@@ -700,7 +700,7 @@ bool IncomingPacket::_doNETWORK_CONFIG_REQUEST(const RuntimeEnvironment *RR,cons
outp.append((unsigned char)Packet::ERROR_OBJ_NOT_FOUND);
outp.append(nwid);
outp.armor(peer->key(),true);
- RR->node->putPacket(_remoteAddress,outp.data(),outp.size());
+ RR->node->putPacket(_localInterfaceId,_remoteAddress,outp.data(),outp.size());
} break;
case NetworkController::NETCONF_QUERY_ACCESS_DENIED: {
@@ -710,7 +710,7 @@ bool IncomingPacket::_doNETWORK_CONFIG_REQUEST(const RuntimeEnvironment *RR,cons
outp.append((unsigned char)Packet::ERROR_NETWORK_ACCESS_DENIED_);
outp.append(nwid);
outp.armor(peer->key(),true);
- RR->node->putPacket(_remoteAddress,outp.data(),outp.size());
+ RR->node->putPacket(_localInterfaceId,_remoteAddress,outp.data(),outp.size());
} break;
case NetworkController::NETCONF_QUERY_INTERNAL_SERVER_ERROR:
@@ -732,7 +732,7 @@ bool IncomingPacket::_doNETWORK_CONFIG_REQUEST(const RuntimeEnvironment *RR,cons
outp.append((unsigned char)Packet::ERROR_UNSUPPORTED_OPERATION);
outp.append(nwid);
outp.armor(peer->key(),true);
- RR->node->putPacket(_remoteAddress,outp.data(),outp.size());
+ RR->node->putPacket(_localInterfaceId,_remoteAddress,outp.data(),outp.size());
}
} catch (std::exception &exc) {
TRACE("dropped NETWORK_CONFIG_REQUEST from %s(%s): unexpected exception: %s",source().toString().c_str(),_remoteAddress.toString().c_str(),exc.what());
@@ -753,7 +753,7 @@ bool IncomingPacket::_doNETWORK_CONFIG_REFRESH(const RuntimeEnvironment *RR,cons
nw->requestConfiguration();
ptr += 8;
}
- peer->received(RR,_remoteAddress,hops(),packetId(),Packet::VERB_NETWORK_CONFIG_REFRESH,0,Packet::VERB_NOP);
+ peer->received(RR,_localInterfaceId,_remoteAddress,hops(),packetId(),Packet::VERB_NETWORK_CONFIG_REFRESH,0,Packet::VERB_NOP);
} catch (std::exception &exc) {
TRACE("dropped NETWORK_CONFIG_REFRESH from %s(%s): unexpected exception: %s",source().toString().c_str(),_remoteAddress.toString().c_str(),exc.what());
} catch ( ... ) {
@@ -780,11 +780,11 @@ bool IncomingPacket::_doMULTICAST_GATHER(const RuntimeEnvironment *RR,const Shar
outp.append((uint32_t)mg.adi());
if (RR->mc->gather(peer->address(),nwid,mg,outp,gatherLimit)) {
outp.armor(peer->key(),true);
- RR->node->putPacket(_remoteAddress,outp.data(),outp.size());
+ RR->node->putPacket(_localInterfaceId,_remoteAddress,outp.data(),outp.size());
}
}
- peer->received(RR,_remoteAddress,hops(),packetId(),Packet::VERB_MULTICAST_GATHER,0,Packet::VERB_NOP);
+ peer->received(RR,_localInterfaceId,_remoteAddress,hops(),packetId(),Packet::VERB_MULTICAST_GATHER,0,Packet::VERB_NOP);
} catch (std::exception &exc) {
TRACE("dropped MULTICAST_GATHER from %s(%s): unexpected exception: %s",source().toString().c_str(),_remoteAddress.toString().c_str(),exc.what());
} catch ( ... ) {
@@ -871,12 +871,12 @@ bool IncomingPacket::_doMULTICAST_FRAME(const RuntimeEnvironment *RR,const Share
outp.append((unsigned char)0x02); // flag 0x02 = contains gather results
if (RR->mc->gather(peer->address(),nwid,to,outp,gatherLimit)) {
outp.armor(peer->key(),true);
- RR->node->putPacket(_remoteAddress,outp.data(),outp.size());
+ RR->node->putPacket(_localInterfaceId,_remoteAddress,outp.data(),outp.size());
}
}
} // else ignore -- not a member of this network
- peer->received(RR,_remoteAddress,hops(),packetId(),Packet::VERB_MULTICAST_FRAME,0,Packet::VERB_NOP);
+ peer->received(RR,_localInterfaceId,_remoteAddress,hops(),packetId(),Packet::VERB_MULTICAST_FRAME,0,Packet::VERB_NOP);
} catch (std::exception &exc) {
TRACE("dropped MULTICAST_FRAME from %s(%s): unexpected exception: %s",source().toString().c_str(),_remoteAddress.toString().c_str(),exc.what());
} catch ( ... ) {
@@ -905,14 +905,14 @@ bool IncomingPacket::_doPUSH_DIRECT_PATHS(const RuntimeEnvironment *RR,const Sha
InetAddress a(field(ptr,4),4,at<uint16_t>(ptr + 4));
if ( ((flags & (0x01 | 0x02)) == 0) && (Path::isAddressValidForPath(a)) ) {
TRACE("attempting to contact %s at pushed direct path %s",peer->address().toString().c_str(),a.toString().c_str());
- peer->attemptToContactAt(RR,a,RR->node->now());
+ peer->attemptToContactAt(RR,_localInterfaceId,a,RR->node->now());
}
} break;
case 6: {
InetAddress a(field(ptr,16),16,at<uint16_t>(ptr + 16));
if ( ((flags & (0x01 | 0x02)) == 0) && (Path::isAddressValidForPath(a)) ) {
TRACE("attempting to contact %s at pushed direct path %s",peer->address().toString().c_str(),a.toString().c_str());
- peer->attemptToContactAt(RR,a,RR->node->now());
+ peer->attemptToContactAt(RR,_localInterfaceId,a,RR->node->now());
}
} break;
}
@@ -934,7 +934,7 @@ void IncomingPacket::_sendErrorNeedCertificate(const RuntimeEnvironment *RR,cons
outp.append((unsigned char)Packet::ERROR_NEED_MEMBERSHIP_CERTIFICATE);
outp.append(nwid);
outp.armor(peer->key(),true);
- RR->node->putPacket(_remoteAddress,outp.data(),outp.size());
+ RR->node->putPacket(_localInterfaceId,_remoteAddress,outp.data(),outp.size());
}
} // namespace ZeroTier
diff --git a/node/IncomingPacket.hpp b/node/IncomingPacket.hpp
index 3bf7737d..170ab7f9 100644
--- a/node/IncomingPacket.hpp
+++ b/node/IncomingPacket.hpp
@@ -72,14 +72,16 @@ public:
*
* @param data Packet data
* @param len Packet length
+ * @param localInterfaceId Local interface ID
* @param remoteAddress Address from which packet came
* @param now Current time
* @throws std::out_of_range Range error processing packet
*/
- IncomingPacket(const void *data,unsigned int len,const InetAddress &remoteAddress,uint64_t now) :
+ IncomingPacket(const void *data,unsigned int len,int localInterfaceId,const InetAddress &remoteAddress,uint64_t now) :
Packet(data,len),
_receiveTime(now),
_remoteAddress(remoteAddress),
+ _localInterfaceId(localInterfaceId),
__refCount()
{
}
@@ -128,6 +130,7 @@ private:
uint64_t _receiveTime;
InetAddress _remoteAddress;
+ int _localInterfaceId;
AtomicCounter __refCount;
};
diff --git a/node/Node.cpp b/node/Node.cpp
index c8c50d66..f9559ab4 100644
--- a/node/Node.cpp
+++ b/node/Node.cpp
@@ -157,13 +157,14 @@ Node::~Node()
ZT1_ResultCode Node::processWirePacket(
uint64_t now,
+ int localInterfaceId,
const struct sockaddr_storage *remoteAddress,
const void *packetData,
unsigned int packetLength,
volatile uint64_t *nextBackgroundTaskDeadline)
{
_now = now;
- RR->sw->onRemotePacket(*(reinterpret_cast<const InetAddress *>(remoteAddress)),packetData,packetLength);
+ RR->sw->onRemotePacket(localInterfaceId,*(reinterpret_cast<const InetAddress *>(remoteAddress)),packetData,packetLength);
return ZT1_RESULT_OK;
}
@@ -261,7 +262,7 @@ ZT1_ResultCode Node::processBackgroundTasks(uint64_t now,volatile uint64_t *next
if (nr->second) {
SharedPtr<Peer> rp(RR->topology->getPeer(nr->first));
if ((rp)&&(!rp->hasActiveDirectPath(now)))
- rp->attemptToContactAt(RR,nr->second,now);
+ rp->attemptToContactAt(RR,-1,nr->second,now);
}
}
@@ -569,13 +570,14 @@ void ZT1_Node_delete(ZT1_Node *node)
enum ZT1_ResultCode ZT1_Node_processWirePacket(
ZT1_Node *node,
uint64_t now,
+ int localInterfaceId,
const struct sockaddr_storage *remoteAddress,
const void *packetData,
unsigned int packetLength,
volatile uint64_t *nextBackgroundTaskDeadline)
{
try {
- return reinterpret_cast<ZeroTier::Node *>(node)->processWirePacket(now,remoteAddress,packetData,packetLength,nextBackgroundTaskDeadline);
+ return reinterpret_cast<ZeroTier::Node *>(node)->processWirePacket(now,localInterfaceId,remoteAddress,packetData,packetLength,nextBackgroundTaskDeadline);
} catch (std::bad_alloc &exc) {
return ZT1_RESULT_FATAL_ERROR_OUT_OF_MEMORY;
} catch ( ... ) {
diff --git a/node/Node.hpp b/node/Node.hpp
index 2a283eab..0e614e5a 100644
--- a/node/Node.hpp
+++ b/node/Node.hpp
@@ -80,6 +80,7 @@ public:
ZT1_ResultCode processWirePacket(
uint64_t now,
+ int localInterfaceId,
const struct sockaddr_storage *remoteAddress,
const void *packetData,
unsigned int packetLength,
@@ -119,16 +120,18 @@ public:
/**
* Enqueue a ZeroTier message to be sent
*
+ * @param localInterfaceId Local interface ID, -1 for unspecified/random
* @param addr Destination address
* @param data Packet data
* @param len Packet length
* @return True if packet appears to have been sent
*/
- inline bool putPacket(const InetAddress &addr,const void *data,unsigned int len)
+ inline bool putPacket(int localInterfaceId,const InetAddress &addr,const void *data,unsigned int len)
{
return (_wirePacketSendFunction(
reinterpret_cast<ZT1_Node *>(this),
_uPtr,
+ localInterfaceId,
reinterpret_cast<const struct sockaddr_storage *>(&addr),
data,
len) == 0);
diff --git a/node/Peer.cpp b/node/Peer.cpp
index 05b14da0..e966a9bf 100644
--- a/node/Peer.cpp
+++ b/node/Peer.cpp
@@ -64,6 +64,7 @@ Peer::Peer(const Identity &myIdentity,const Identity &peerIdentity)
void Peer::received(
const RuntimeEnvironment *RR,
+ int localInterfaceId,
const InetAddress &remoteAddr,
unsigned int hops,
uint64_t packetId,
@@ -81,7 +82,7 @@ void Peer::received(
{
unsigned int np = _numPaths;
for(unsigned int p=0;p<np;++p) {
- if (_paths[p].address() == remoteAddr) {
+ if ((_paths[p].address() == remoteAddr)&&(_paths[p].localInterfaceId() == localInterfaceId)) {
_paths[p].received(now);
pathIsConfirmed = true;
break;
@@ -106,7 +107,7 @@ void Peer::received(
}
}
if (slot) {
- *slot = RemotePath(remoteAddr,false);
+ *slot = RemotePath(localInterfaceId,remoteAddr,false);
slot->received(now);
_numPaths = np;
pathIsConfirmed = true;
@@ -119,7 +120,7 @@ void Peer::received(
if ((now - _lastPathConfirmationSent) >= ZT_MIN_PATH_CONFIRMATION_INTERVAL) {
_lastPathConfirmationSent = now;
TRACE("got %s via unknown path %s(%s), confirming...",Packet::verbString(verb),_id.address().toString().c_str(),remoteAddr.toString().c_str());
- attemptToContactAt(RR,remoteAddr,now);
+ attemptToContactAt(RR,localInterfaceId,remoteAddr,now);
}
}
}
@@ -141,7 +142,7 @@ void Peer::received(
for(std::vector<MulticastGroup>::const_iterator mg(mgs.begin());mg!=mgs.end();++mg) {
if ((outp.size() + 18) > ZT_UDP_DEFAULT_PAYLOAD_MTU) {
outp.armor(_key,true);
- RR->node->putPacket(remoteAddr,outp.data(),outp.size());
+ RR->node->putPacket(localInterfaceId,remoteAddr,outp.data(),outp.size());
outp.reset(_id.address(),RR->identity.address(),Packet::VERB_MULTICAST_LIKE);
}
@@ -154,7 +155,7 @@ void Peer::received(
}
if (outp.size() > ZT_PROTO_MIN_PACKET_LENGTH) {
outp.armor(_key,true);
- RR->node->putPacket(remoteAddr,outp.data(),outp.size());
+ RR->node->putPacket(localInterfaceId,remoteAddr,outp.data(),outp.size());
}
}
}
@@ -180,7 +181,7 @@ RemotePath *Peer::getBestPath(uint64_t now)
return bestPath;
}
-void Peer::attemptToContactAt(const RuntimeEnvironment *RR,const InetAddress &atAddress,uint64_t now)
+void Peer::attemptToContactAt(const RuntimeEnvironment *RR,int localInterfaceId,const InetAddress &atAddress,uint64_t now)
{
Packet outp(_id.address(),RR->identity.address(),Packet::VERB_HELLO);
outp.append((unsigned char)ZT_PROTO_VERSION);
@@ -208,7 +209,7 @@ void Peer::attemptToContactAt(const RuntimeEnvironment *RR,const InetAddress &at
}
outp.armor(_key,false); // HELLO is sent in the clear
- RR->node->putPacket(atAddress,outp.data(),outp.size());
+ RR->node->putPacket(localInterfaceId,atAddress,outp.data(),outp.size());
}
void Peer::doPingAndKeepalive(const RuntimeEnvironment *RR,uint64_t now)
@@ -217,12 +218,12 @@ void Peer::doPingAndKeepalive(const RuntimeEnvironment *RR,uint64_t now)
if (bestPath) {
if ((now - bestPath->lastReceived()) >= ZT_PEER_DIRECT_PING_DELAY) {
TRACE("PING %s(%s)",_id.address().toString().c_str(),bestPath->address().toString().c_str());
- attemptToContactAt(RR,bestPath->address(),now);
+ attemptToContactAt(RR,bestPath->localInterfaceId(),bestPath->address(),now);
bestPath->sent(now);
} else if (((now - bestPath->lastSend()) >= ZT_NAT_KEEPALIVE_DELAY)&&(!bestPath->reliable())) {
_natKeepaliveBuf += (uint32_t)((now * 0x9e3779b1) >> 1); // tumble this around to send constantly varying (meaningless) payloads
TRACE("NAT keepalive %s(%s)",_id.address().toString().c_str(),bestPath->address().toString().c_str());
- RR->node->putPacket(bestPath->address(),&_natKeepaliveBuf,sizeof(_natKeepaliveBuf));
+ RR->node->putPacket(bestPath->localInterfaceId(),bestPath->address(),&_natKeepaliveBuf,sizeof(_natKeepaliveBuf));
bestPath->sent(now);
}
}
@@ -354,7 +355,7 @@ bool Peer::resetWithinScope(const RuntimeEnvironment *RR,InetAddress::IpScope sc
while (x < np) {
if (_paths[x].address().ipScope() == scope) {
if (_paths[x].fixed()) {
- attemptToContactAt(RR,_paths[x].address(),now);
+ attemptToContactAt(RR,_paths[x].localInterfaceId(),_paths[x].address(),now);
_paths[y++] = _paths[x]; // keep fixed paths
}
} else {
diff --git a/node/Peer.hpp b/node/Peer.hpp
index ef436cd9..b0f2b4e2 100644
--- a/node/Peer.hpp
+++ b/node/Peer.hpp
@@ -105,6 +105,7 @@ public:
* and appears to be valid.
*
* @param RR Runtime environment
+ * @param localInterfaceId Local interface ID or -1 if unspecified
* @param remoteAddr Internet address of sender
* @param hops ZeroTier (not IP) hops
* @param packetId Packet ID
@@ -114,6 +115,7 @@ public:
*/
void received(
const RuntimeEnvironment *RR,
+ int localInterfaceId,
const InetAddress &remoteAddr,
unsigned int hops,
uint64_t packetId,
@@ -155,10 +157,11 @@ public:
* for NAT traversal and path verification.
*
* @param RR Runtime environment
+ * @param localInterfaceId Local interface ID or -1 for unspecified
* @param atAddress Destination address
* @param now Current time
*/
- void attemptToContactAt(const RuntimeEnvironment *RR,const InetAddress &atAddress,uint64_t now);
+ void attemptToContactAt(const RuntimeEnvironment *RR,int localInterfaceId,const InetAddress &atAddress,uint64_t now);
/**
* Send pings or keepalives depending on configured timeouts
diff --git a/node/RemotePath.hpp b/node/RemotePath.hpp
index 291943c9..a7ef141b 100644
--- a/node/RemotePath.hpp
+++ b/node/RemotePath.hpp
@@ -53,14 +53,18 @@ public:
Path(),
_lastSend(0),
_lastReceived(0),
+ _localInterfaceId(-1),
_fixed(false) {}
- RemotePath(const InetAddress &addr,bool fixed) :
+ RemotePath(int localInterfaceId,const InetAddress &addr,bool fixed) :
Path(addr,0,TRUST_NORMAL),
_lastSend(0),
_lastReceived(0),
+ _localInterfaceId(localInterfaceId),
_fixed(fixed) {}
+ inline int localInterfaceId() const throw() { return _localInterfaceId; }
+
inline uint64_t lastSend() const throw() { return _lastSend; }
inline uint64_t lastReceived() const throw() { return _lastReceived; }
@@ -123,7 +127,7 @@ public:
*/
inline bool send(const RuntimeEnvironment *RR,const void *data,unsigned int len,uint64_t now)
{
- if (RR->node->putPacket(address(),data,len)) {
+ if (RR->node->putPacket(_localInterfaceId,address(),data,len)) {
sent(now);
RR->antiRec->logOutgoingZT(data,len);
return true;
@@ -134,6 +138,7 @@ public:
private:
uint64_t _lastSend;
uint64_t _lastReceived;
+ int _localInterfaceId;
bool _fixed;
};
diff --git a/node/Switch.cpp b/node/Switch.cpp
index 995abef4..0de94400 100644
--- a/node/Switch.cpp
+++ b/node/Switch.cpp
@@ -78,8 +78,11 @@ Switch::~Switch()
{
}
-void Switch::onRemotePacket(const InetAddress &fromAddr,const void *data,unsigned int len)
+void Switch::onRemotePacket(int localInterfaceId,const InetAddress &fromAddr,const void *data,unsigned int len)
{
+ if (localInterfaceId < 0)
+ localInterfaceId = 0;
+
try {
if (len == 13) {
/* LEGACY: before VERB_PUSH_DIRECT_PATHS, peers used broadcast
@@ -96,14 +99,14 @@ void Switch::onRemotePacket(const InetAddress &fromAddr,const void *data,unsigne
_lastBeaconResponse = now;
Packet outp(peer->address(),RR->identity.address(),Packet::VERB_NOP);
outp.armor(peer->key(),false);
- RR->node->putPacket(fromAddr,outp.data(),outp.size());
+ RR->node->putPacket(localInterfaceId,fromAddr,outp.data(),outp.size());
}
}
} else if (len > ZT_PROTO_MIN_FRAGMENT_LENGTH) {
if (((const unsigned char *)data)[ZT_PACKET_FRAGMENT_IDX_FRAGMENT_INDICATOR] == ZT_PACKET_FRAGMENT_INDICATOR) {
- _handleRemotePacketFragment(fromAddr,data,len);
+ _handleRemotePacketFragment(localInterfaceId,fromAddr,data,len);
} else if (len >= ZT_PROTO_MIN_PACKET_LENGTH) {
- _handleRemotePacketHead(fromAddr,data,len);
+ _handleRemotePacketHead(localInterfaceId,fromAddr,data,len);
}
}
} catch (std::exception &ex) {
@@ -376,14 +379,14 @@ bool Switch::unite(const Address &p1,const Address &p2,bool force)
return true;
}
-void Switch::rendezvous(const SharedPtr<Peer> &peer,const InetAddress &atAddr)
+void Switch::rendezvous(const SharedPtr<Peer> &peer,int localInterfaceId,const InetAddress &atAddr)
{
TRACE("sending NAT-t message to %s(%s)",peer->address().toString().c_str(),atAddr.toString().c_str());
const uint64_t now = RR->node->now();
- peer->attemptToContactAt(RR,atAddr,now);
+ peer->attemptToContactAt(RR,localInterfaceId,atAddr,now);
{
Mutex::Lock _l(_contactQueue_m);
- _contactQueue.push_back(ContactQueueEntry(peer,now + ZT_NAT_T_TACTICAL_ESCALATION_DELAY,atAddr));
+ _contactQueue.push_back(ContactQueueEntry(peer,now + ZT_NAT_T_TACTICAL_ESCALATION_DELAY,localInterfaceId,atAddr));
}
}
@@ -453,14 +456,14 @@ unsigned long Switch::doTimerTasks(uint64_t now)
} else {
if (qi->strategyIteration == 0) {
// First strategy: send packet directly to destination
- qi->peer->attemptToContactAt(RR,qi->inaddr,now);
+ qi->peer->attemptToContactAt(RR,qi->localInterfaceId,qi->inaddr,now);
} else if (qi->strategyIteration <= 4) {
// Strategies 1-4: try escalating ports for symmetric NATs that remap sequentially
InetAddress tmpaddr(qi->inaddr);
int p = (int)qi->inaddr.port() + qi->strategyIteration;
if (p < 0xffff) {
tmpaddr.setPort((unsigned int)p);
- qi->peer->attemptToContactAt(RR,tmpaddr,now);
+ qi->peer->attemptToContactAt(RR,qi->localInterfaceId,tmpaddr,now);
} else qi->strategyIteration = 5;
} else {
// All strategies tried, expire entry
@@ -551,7 +554,7 @@ unsigned long Switch::doTimerTasks(uint64_t now)
return nextDelay;
}
-void Switch::_handleRemotePacketFragment(const InetAddress &fromAddr,const void *data,unsigned int len)
+void Switch::_handleRemotePacketFragment(int localInterfaceId,const InetAddress &fromAddr,const void *data,unsigned int len)
{
Packet::Fragment fragment(data,len);
Address destination(fragment.destination());
@@ -622,9 +625,9 @@ void Switch::_handleRemotePacketFragment(const InetAddress &fromAddr,const void
}
}
-void Switch::_handleRemotePacketHead(const InetAddress &fromAddr,const void *data,unsigned int len)
+void Switch::_handleRemotePacketHead(int localInterfaceId,const InetAddress &fromAddr,const void *data,unsigned int len)
{
- SharedPtr<IncomingPacket> packet(new IncomingPacket(data,len,fromAddr,RR->node->now()));
+ SharedPtr<IncomingPacket> packet(new IncomingPacket(data,len,localInterfaceId,fromAddr,RR->node->now()));
Address source(packet->source());
Address destination(packet->destination());
diff --git a/node/Switch.hpp b/node/Switch.hpp
index 55e2c362..a8d89f41 100644
--- a/node/Switch.hpp
+++ b/node/Switch.hpp
@@ -79,11 +79,12 @@ public:
/**
* Called when a packet is received from the real network
*
+ * @param localInterfaceId Local interface ID or -1 for unspecified
* @param fromAddr Internet IP address of origin
* @param data Packet data
* @param len Packet length
*/
- void onRemotePacket(const InetAddress &fromAddr,const void *data,unsigned int len);
+ void onRemotePacket(int localInterfaceId,const InetAddress &fromAddr,const void *data,unsigned int len);
/**
* Called when a packet comes from a local Ethernet tap
@@ -140,9 +141,10 @@ public:
* Attempt NAT traversal to peer at a given physical address
*
* @param peer Peer to contact
+ * @param localInterfaceId Local interface ID or -1 if unspecified
* @param atAddr Address of peer
*/
- void rendezvous(const SharedPtr<Peer> &peer,const InetAddress &atAddr);
+ void rendezvous(const SharedPtr<Peer> &peer,int localInterfaceId,const InetAddress &atAddr);
/**
* Request WHOIS on a given address
@@ -179,8 +181,8 @@ public:
unsigned long doTimerTasks(uint64_t now);
private:
- void _handleRemotePacketFragment(const InetAddress &fromAddr,const void *data,unsigned int len);
- void _handleRemotePacketHead(const InetAddress &fromAddr,const void *data,unsigned int len);
+ void _handleRemotePacketFragment(int localInterfaceId,const InetAddress &fromAddr,const void *data,unsigned int len);
+ void _handleRemotePacketHead(int localInterfaceId,const InetAddress &fromAddr,const void *data,unsigned int len);
Address _sendWhoisRequest(const Address &addr,const Address *peersAlreadyConsulted,unsigned int numPeersAlreadyConsulted);
bool _trySend(const Packet &packet,bool encrypt,uint64_t nwid);
@@ -260,15 +262,17 @@ private:
struct ContactQueueEntry
{
ContactQueueEntry() {}
- ContactQueueEntry(const SharedPtr<Peer> &p,uint64_t ft,const InetAddress &a) :
+ ContactQueueEntry(const SharedPtr<Peer> &p,uint64_t ft,int liid,const InetAddress &a) :
peer(p),
fireAtTime(ft),
inaddr(a),
+ localInterfaceId(liid),
strategyIteration(0) {}
SharedPtr<Peer> peer;
uint64_t fireAtTime;
InetAddress inaddr;
+ int localInterfaceId;
unsigned int strategyIteration;
};
std::list<ContactQueueEntry> _contactQueue;
diff --git a/node/Topology.cpp b/node/Topology.cpp
index 25a92acd..c63ed9f4 100644
--- a/node/Topology.cpp
+++ b/node/Topology.cpp
@@ -62,7 +62,7 @@ void Topology::setRootServers(const std::map< Identity,std::vector<InetAddress>
if (!p)
p = SharedPtr<Peer>(new Peer(RR->identity,i->first));
for(std::vector<InetAddress>::const_iterator j(i->second.begin());j!=i->second.end();++j)
- p->addPath(RemotePath(*j,true));
+ p->addPath(RemotePath(0,*j,true));
p->use(now);
_rootPeers.push_back(p);
}
diff --git a/service/OneService.cpp b/service/OneService.cpp
index e8b8ba60..c2b4636f 100644
--- a/service/OneService.cpp
+++ b/service/OneService.cpp
@@ -344,7 +344,7 @@ static int SnodeVirtualNetworkConfigFunction(ZT1_Node *node,void *uptr,uint64_t
static void SnodeEventCallback(ZT1_Node *node,void *uptr,enum ZT1_Event event,const void *metaData);
static long SnodeDataStoreGetFunction(ZT1_Node *node,void *uptr,const char *name,void *buf,unsigned long bufSize,unsigned long readIndex,unsigned long *totalSize);
static int SnodeDataStorePutFunction(ZT1_Node *node,void *uptr,const char *name,const void *data,unsigned long len,int secure);
-static int SnodeWirePacketSendFunction(ZT1_Node *node,void *uptr,const struct sockaddr_storage *addr,const void *data,unsigned int len);
+static int SnodeWirePacketSendFunction(ZT1_Node *node,void *uptr,int localInterfaceId,const struct sockaddr_storage *addr,const void *data,unsigned int len);
static void SnodeVirtualNetworkFrameFunction(ZT1_Node *node,void *uptr,uint64_t nwid,uint64_t sourceMac,uint64_t destMac,unsigned int etherType,unsigned int vlanId,const void *data,unsigned int len);
static void StapFrameHandler(void *uptr,uint64_t nwid,const MAC &from,const MAC &to,unsigned int etherType,unsigned int vlanId,const void *data,unsigned int len);
@@ -727,6 +727,7 @@ public:
_lastDirectReceiveFromGlobal = OSUtils::now();
ZT1_ResultCode rc = _node->processWirePacket(
OSUtils::now(),
+ 0,
(const struct sockaddr_storage *)from, // Phy<> uses sockaddr_storage, so it'll always be that big
data,
len,
@@ -875,6 +876,7 @@ public:
if (from) {
ZT1_ResultCode rc = _node->processWirePacket(
OSUtils::now(),
+ 0,
reinterpret_cast<struct sockaddr_storage *>(&from),
data,
plen,
@@ -1288,7 +1290,7 @@ static long SnodeDataStoreGetFunction(ZT1_Node *node,void *uptr,const char *name
{ return reinterpret_cast<OneServiceImpl *>(uptr)->nodeDataStoreGetFunction(name,buf,bufSize,readIndex,totalSize); }
static int SnodeDataStorePutFunction(ZT1_Node *node,void *uptr,const char *name,const void *data,unsigned long len,int secure)
{ return reinterpret_cast<OneServiceImpl *>(uptr)->nodeDataStorePutFunction(name,data,len,secure); }
-static int SnodeWirePacketSendFunction(ZT1_Node *node,void *uptr,const struct sockaddr_storage *addr,const void *data,unsigned int len)
+static int SnodeWirePacketSendFunction(ZT1_Node *node,void *uptr,int localInterfaceId,const struct sockaddr_storage *addr,const void *data,unsigned int len)
{ return reinterpret_cast<OneServiceImpl *>(uptr)->nodeWirePacketSendFunction(addr,data,len); }
static void SnodeVirtualNetworkFrameFunction(ZT1_Node *node,void *uptr,uint64_t nwid,uint64_t sourceMac,uint64_t destMac,unsigned int etherType,unsigned int vlanId,const void *data,unsigned int len)
{ reinterpret_cast<OneServiceImpl *>(uptr)->nodeVirtualNetworkFrameFunction(nwid,sourceMac,destMac,etherType,vlanId,data,len); }