diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index 15c9eedd9..bc7b73a3c 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -82,6 +82,7 @@ SOURCES += tcponudp/udppeer.cc \ tcponudp/tcpstream.cc \ tcponudp/tou.cc \ tcponudp/bss_tou.c \ + tcponudp/udpstunner.cc \ tcponudp/udprelay.cc \ # These two aren't actually used (and don't compile) .... diff --git a/libretroshare/src/pqi/pqissludp.cc b/libretroshare/src/pqi/pqissludp.cc index 8d8bec7f1..5f9030dd6 100644 --- a/libretroshare/src/pqi/pqissludp.cc +++ b/libretroshare/src/pqi/pqissludp.cc @@ -99,7 +99,9 @@ int pqissludp::reset() int pqissludp::attach() { - sockfd = tou_socket(0,0,0); + // IN THE IMPROVED TOU LIBRARY, we need to be careful with the tou_socket PARAMETERS. + // For now, this should do! + sockfd = tou_socket(0,TOU_RECEIVER_TYPE_UDPPEER,0); if (0 > sockfd) { rslog(RSL_WARNING, pqissludpzone, diff --git a/libretroshare/src/rsserver/rsinit.cc b/libretroshare/src/rsserver/rsinit.cc index 5966ebfa9..2090b94da 100644 --- a/libretroshare/src/rsserver/rsinit.cc +++ b/libretroshare/src/rsserver/rsinit.cc @@ -1740,6 +1740,8 @@ RsTurtle *rsTurtle = NULL ; #ifdef RS_USE_BITDHT #include "dht/p3bitdht.h" #include "udp/udpstack.h" +#include "tcponudp/udppeer.h" +#include "tcponudp/udprelay.h" #endif /**** @@ -1883,11 +1885,53 @@ int RsServer::StartupRetroShare() } } - p3BitDht *mBitDht = new p3BitDht(ownId, mConnMgr, - mUdpStack, bootstrapfile); + /* construct the rest of the stack, important to build them in the correct order! */ + /* MOST OF THIS IS COMMENTED OUT UNTIL THE REST OF libretroshare IS READY FOR IT! */ + + UdpSubReceiver *udpReceivers[3]; + int udpTypes[3]; + + // BITDHT FIRST. + p3BitDht *mBitDht = new p3BitDht(ownId, mConnMgr, + mUdpStack, bootstrapfile); + + // THEN STUNNER. + //UdpStunner *mDhtStunner = new UdpStunner(mUdpStack); + + // NEXT THE RELAY (NEED to keep a reference for installing RELAYS) + //UdpRelayReceiver *mRelayRecver = new UdpRelayReceiver(mUdpStack); + //udpReceivers[2] = mRelayRecver; /* RELAY Connections (DHT Port) */ + //udpTypes[2] = TOU_RECEIVER_TYPE_UDPRELAY; + //mUdpStack->addReceiver(udpReceivers[2]); + + // LAST ON THIS STACK IS STANDARD DIRECT TOU + udpReceivers[0] = new UdpPeerReceiver(mUdpStack); /* standard DIRECT Connections (DHT Port) */ + udpTypes[0] = TOU_RECEIVER_TYPE_UDPPEER; + mUdpStack->addReceiver(udpReceivers[0]); + + // NOW WE BUILD THE SECOND STACK. + // Create the Second UdpStack... Port should be random (but openable!). + //struct sockaddr_in sndladdr; + //sockaddr_clear(&sndladdr); + //sndladdr.sin_port = htons(RsInitConfig::port + 1111); + //rsUdpStack *mUdpProxyStack = new rsUdpStack(sndladdr); + + // FIRSTLY THE PROXY STUNNER. + //UdpStunner *mProxyStunner = new UdpStunner(mUdpProxyStack); + + // FINALLY THE PROXY UDP CONNECTIONS + //udpReceivers[1] = new UdpPeerReceiver(mUdpProxyStack); /* PROXY Connections (Alt UDP Port) */ + //udpTypes[1] = TOU_RECEIVER_TYPE_UDPPEER; + //mUdpProxyStack->addReceiver(udpReceivers[1]); + + + // NOW WE CAN PASS THE RECEIVERS TO TOU. + // temp initialisation of only the DIRECT TOU. + tou_init((void **) udpReceivers, udpTypes, 1); + + // REAL INITIALISATION - WITH THREE MODES - FOR LATER. + //tou_init((void **) udpReceivers, udpTypes, 3); - /* construct the rest of the stack */ - tou_init(mUdpStack); #endif diff --git a/libretroshare/src/tcponudp/tcpstream.cc b/libretroshare/src/tcponudp/tcpstream.cc index a2f831d69..a545c8f47 100644 --- a/libretroshare/src/tcponudp/tcpstream.cc +++ b/libretroshare/src/tcponudp/tcpstream.cc @@ -71,7 +71,7 @@ static const double RTT_ALPHA = 0.875; // platform independent fractional timestamp. static double getCurrentTS(); -TcpStream::TcpStream(UdpPeerReceiver *lyr) +TcpStream::TcpStream(UdpSubReceiver *lyr) :inSize(0), outSizeRead(0), outSizeNet(0), state(TCP_CLOSED), inStreamActive(false), diff --git a/libretroshare/src/tcponudp/tcpstream.h b/libretroshare/src/tcponudp/tcpstream.h index 8bd05b2e5..29c627554 100644 --- a/libretroshare/src/tcponudp/tcpstream.h +++ b/libretroshare/src/tcponudp/tcpstream.h @@ -73,7 +73,7 @@ class TcpStream: public UdpPeer public: /* Top-Level exposed */ - TcpStream(UdpPeerReceiver *udp); + TcpStream(UdpSubReceiver *udp); virtual ~TcpStream() { return; } /* user interface */ @@ -230,8 +230,8 @@ uint32 int_rbytes(); struct sockaddr_in peeraddr; bool peerKnown; - /* UdpPeerReceiver (has own Mutex!) */ - UdpPeerReceiver *udp; + /* UdpSubReceiver (has own Mutex!) */ + UdpSubReceiver *udp; }; diff --git a/libretroshare/src/tcponudp/tou.cc b/libretroshare/src/tcponudp/tou.cc index f93a2b1fc..774a7340c 100644 --- a/libretroshare/src/tcponudp/tou.cc +++ b/libretroshare/src/tcponudp/tou.cc @@ -47,6 +47,8 @@ struct TcpOnUdp_t int tou_fd; int lasterrno; TcpStream *tcp; + UdpSubReceiver *udpsr; + int udptype; bool idle; }; @@ -57,42 +59,82 @@ static std::vector tou_streams; static int tou_inited = 0; -#include "udp/udpstack.h" #include "tcponudp/udppeer.h" +#include "tcponudp/udprelay.h" -static UdpStack *udpstack = NULL; -static UdpPeerReceiver *udps = NULL; +static UdpSubReceiver *udpSR[MAX_TOU_RECEIVERS] = {NULL}; +static uint32_t udpType[MAX_TOU_RECEIVERS] = {NULL}; +static uint32_t noUdpSR = 0; static int tou_tick_all(); +/* tou_init + * + * Modified to accept a number of UdpSubRecievers! + * these can be linked to arbitary UdpStacks. + * (removed all UdpStack references here!) + * + * Unfortunately, the UdpSubReceivers have different initialisation for starting a connection. + * So the TOU interface has to accomodate this. + * + * UdpSubReceive /* tou_init - opens the udp port (universal bind) */ -int tou_init(void *in_udpstack) +int tou_init(void **in_udpsubrecvs, int *type, int number) { - UdpStack *stack = (UdpStack *) in_udpstack; + UdpSubReceiver **usrArray = (UdpSubReceiver **) in_udpsubrecvs; + if (number > MAX_TOU_RECEIVERS) + { + std::cerr << "tou_init() Invalid number of receivers"; + std::cerr << std::endl; + return 0; + } + if (tou_inited) { return 1; } - tou_streams.resize(kInitStreamTable); + noUdpSR = number; + int i; + for(i = 0; i < noUdpSR; i++) + { + udpSR[i] = usrArray[i]; + udpType[i] = type[i]; + } - udpstack = stack; - udps = new UdpPeerReceiver(stack); - stack->addReceiver(udps); + tou_streams.resize(kInitStreamTable); tou_inited = 1; return 1; } -/* open - which does nothing */ -int tou_socket(int /*domain*/, int /*type*/, int /*protocol*/) +/* open - allocates a sockfd, and checks that the type is okay */ +int tou_socket(int recvIdx, int type, int /*protocol*/) { if (!tou_inited) { return -1; } + if (recvIdx >= noUdpSR) + { + std::cerr << "tou_socket() ERROR recvIdx greater than #receivers"; + std::cerr << std::endl; + return -1; + } + + /* check that the index matches the type */ + UdpSubReceiver *recver = udpSR[recvIdx]; + uint32_t recverType = udpType[recvIdx]; + + if (recverType != type) + { + std::cerr << "tou_socket() ERROR type doesn't match expected type"; + std::cerr << std::endl; + return -1; + } + for(unsigned int i = 1; i < tou_streams.size(); i++) { if (tou_streams[i] == NULL) @@ -100,6 +142,8 @@ int tou_socket(int /*domain*/, int /*type*/, int /*protocol*/) tou_streams[i] = new TcpOnUdp(); tou_streams[i] -> tou_fd = i; tou_streams[i] -> tcp = NULL; + tou_streams[i] -> udpsr = recver; + tou_streams[i] -> udptype = recverType; return i; } } @@ -112,6 +156,8 @@ int tou_socket(int /*domain*/, int /*type*/, int /*protocol*/) { tou -> tou_fd = tou_streams.size() -1; tou -> tcp = NULL; + tou -> udpsr = recver; + tou -> udptype = recverType; return tou->tou_fd; } @@ -158,11 +204,35 @@ int tou_connect(int sockfd, const struct sockaddr *serv_addr, return -1; } + /* enforce that the udptype is correct */ + if (tous -> udptype != TOU_RECEIVER_TYPE_UDPPEER) + { + std::cerr << "tou_connect() ERROR connect method invalid for udptype"; + std::cerr << std::endl; + tous -> lasterrno = EINVAL; + return -1; + } + + +#ifdef TOU_DYNAMIC_CAST_CHECK + /* extra checking -> for testing purposes (dynamic cast) */ + UdpPeerReceiver *upr = dynamic_cast(tous->udpsr); + if (!upr) + { + std::cerr << "tou_connect() ERROR cannot convert type to UdpPeerReceiver"; + std::cerr << std::endl; + tous -> lasterrno = EINVAL; + return -1; + } +#else + UdpPeerReceiver *upr = (UdpPeerReceiver *) (tous->udpsr); +#endif + /* create a TCP stream to connect with. */ if (!tous->tcp) { - tous->tcp = new TcpStream(udps); - udps->addUdpPeer(tous->tcp, + tous->tcp = new TcpStream(tous->udpsr); + upr->addUdpPeer(tous->tcp, *((const struct sockaddr_in *) serv_addr)); } @@ -178,6 +248,7 @@ int tou_connect(int sockfd, const struct sockaddr *serv_addr, return -1; } +/* is this ever used? should it be depreciated? */ int tou_listenfor(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen) { @@ -193,11 +264,34 @@ int tou_listenfor(int sockfd, const struct sockaddr *serv_addr, return -1; } + /* enforce that the udptype is correct */ + if (tous -> udptype != TOU_RECEIVER_TYPE_UDPPEER) + { + std::cerr << "tou_connect() ERROR connect method invalid for udptype"; + std::cerr << std::endl; + tous -> lasterrno = EINVAL; + return -1; + } + +#ifdef TOU_DYNAMIC_CAST_CHECK + /* extra checking -> for testing purposes (dynamic cast) */ + UdpPeerReceiver *upr = dynamic_cast(tous->udpsr); + if (!upr) + { + std::cerr << "tou_connect() ERROR cannot convert type to UdpPeerReceiver"; + std::cerr << std::endl; + tous -> lasterrno = EINVAL; + return -1; + } +#else + UdpPeerReceiver *upr = (UdpPeerReceiver *) (tous->udpsr); +#endif + /* create a TCP stream to connect with. */ if (!tous->tcp) { - tous->tcp = new TcpStream(udps); - udps->addUdpPeer(tous->tcp, + tous->tcp = new TcpStream(tous->udpsr); + upr->addUdpPeer(tous->tcp, *((const struct sockaddr_in *) serv_addr)); } @@ -214,6 +308,84 @@ int tou_listen(int /* sockfd */ , int /* backlog */ ) return 1; } +/* + * This is the alternative RELAY connection. + * + * User needs to provide 3 ip addresses. + * These addresses should have been provided by the RELAY negogiation + * a) own ip:port + * b) proxy ip:port + * c) dest ip:port + * + * The reset of the startup is similar to other TOU connections. + * As this is likely to be run over an established UDP connection, + * there is little need for a big connection period. + * + * - like a tcp/ip connection, the connect + * will return -1 EAGAIN, until connection complete. + * - always non blocking. + */ +#define DEFAULT_RELAY_CONN_PERIOD 1 + +int tou_connect_via_relay(int sockfd, + const struct sockaddr_in *own_addr, + const struct sockaddr_in *proxy_addr, + const struct sockaddr_in *dest_addr) + +{ + if (tou_streams[sockfd] == NULL) + { + return -1; + } + TcpOnUdp *tous = tou_streams[sockfd]; + + /* enforce that the udptype is correct */ + if (tous -> udptype != TOU_RECEIVER_TYPE_UDPRELAY) + { + std::cerr << "tou_connect() ERROR connect method invalid for udptype"; + std::cerr << std::endl; + tous -> lasterrno = EINVAL; + return -1; + } + +#ifdef TOU_DYNAMIC_CAST_CHECK + /* extra checking -> for testing purposes (dynamic cast) */ + UdpRelayReceiver *urr = dynamic_cast(tous->udpsr); + if (!urr) + { + std::cerr << "tou_connect() ERROR cannot convert type to UdpRelayReceiver"; + std::cerr << std::endl; + tous -> lasterrno = EINVAL; + return -1; + } +#else + UdpRelayReceiver *urr = (UdpRelayReceiver *) (tous->udpsr); +#endif + + /* create a TCP stream to connect with. */ + if (!tous->tcp) + { + tous->tcp = new TcpStream(tous->udpsr); + + UdpRelayAddrSet addrSet(own_addr, dest_addr); + urr->addUdpPeer(tous->tcp, &addrSet, proxy_addr); + } + + /* We Point it at the Destination Address. + * The UdpRelayReceiver wraps and re-directs the packets to the proxy + */ + tous->tcp->connect(*dest_addr, DEFAULT_RELAY_CONN_PERIOD); + tous->tcp->tick(); + tou_tick_all(); + if (tous->tcp->isConnected()) + { + return 0; + } + + tous -> lasterrno = EINPROGRESS; + return -1; +} + /* slightly different - returns sockfd on connection */ int tou_accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) @@ -362,8 +534,50 @@ int tou_close(int sockfd) /* shut it down */ tous->tcp->close(); - udps->removeUdpPeer(tous->tcp); + + /* now we need to work out which type of receiver we have */ +#ifdef TOU_DYNAMIC_CAST_CHECK + /* extra checking -> for testing purposes (dynamic cast) */ + UdpRelayReceiver *urr = dynamic_cast(tous->udpsr); + UdpPeerReceiver *upr = dynamic_cast(tous->udpsr); + if (urr) + { + urr->removeUdpPeer(tous->tcp); + } + else if (upr) + { + upr->removeUdpPeer(tous->tcp); + } + else + { + /* error */ + std::cerr << "tou_close() ERROR unknown udptype"; + std::cerr << std::endl; + tous -> lasterrno = EINVAL; + } +#else + if (tous -> udptype == TOU_RECEIVER_TYPE_UDPRELAY) + { + UdpRelayReceiver *urr = (UdpRelayReceiver *) (tous->udpsr); + urr->removeUdpPeer(tous->tcp); + } + else if (tous -> udptype == TOU_RECEIVER_TYPE_UDPPEER) + { + UdpPeerReceiver *upr = (UdpPeerReceiver *) (tous->udpsr); + upr->removeUdpPeer(tous->tcp); + } + else + { + /* error */ + std::cerr << "tou_close() ERROR unknown udptype"; + std::cerr << std::endl; + tous -> lasterrno = EINVAL; + } + +#endif + delete tous->tcp; + } delete tous; @@ -374,10 +588,6 @@ int tou_close(int sockfd) /* get an error number */ int tou_errno(int sockfd) { - if (!udps) - { - return ENOTSOCK; - } if (tou_streams[sockfd] == NULL) { return ENOTSOCK; diff --git a/libretroshare/src/tcponudp/tou.h b/libretroshare/src/tcponudp/tou.h index 2129e7312..905c7387b 100644 --- a/libretroshare/src/tcponudp/tou.h +++ b/libretroshare/src/tcponudp/tou.h @@ -50,22 +50,34 @@ #endif +#ifdef __cplusplus +extern "C" { +#endif + /* standard C interface (as Unix-like as possible) * for the tou (Tcp On Udp) library */ /* * Init: - * (1) need UdpStack item, which has our address already. + * The TOU library no longer references any UdpStack items. + * instead, two arrays should be passed to the init function. + * int tou_init( (void **) UdpSubReceiver **udpRecvers, int *udpType, int nUdps); + * + * The UdpSubReceivers should be derived classes, with corresponding types: + * UdpPeerReceiver TOU_RECEIVER_TYPE_UDPPEER + * UdpRelayReceiver TOU_RECEIVER_TYPE_UDPRELAY + * */ +#define MAX_TOU_RECEIVERS 16 + +#define TOU_RECEIVER_TYPE_NONE 0x0000 +#define TOU_RECEIVER_TYPE_UDPPEER 0x0001 +#define TOU_RECEIVER_TYPE_UDPRELAY 0x0002 + // hack to avoid classes in C code. (MacOSX complaining) -// will pass as UdpStack * as void * -int tou_init(void *udpStack); +int tou_init(void **udpSubRecvs, int *udpTypes, int nUdps); - -#ifdef __cplusplus -extern "C" { -#endif /* Connections are as similar to UNIX as possible * (1) create a socket: tou_socket() this reserves a socket id. * (2) connect: active: tou_connect() or passive: tou_listenfor(). @@ -77,6 +89,18 @@ extern "C" { * tou_bind() is not valid. tou_init performs this role. * tou_listen() is not valid. (must listen for a specific address) use tou_listenfor() instead. * tou_accept() can still be used. + * + ****** THE ABOVE IS BECOMING LESS TRUE ******** + * + * I have now added Multiple type of TOU Connections (Proxy, Relay), + * and multiple UDP Receivers (meaning you can use different ports too). + * + * The UDP receivers must be specified at startup (new tou_init()) + * and the Receiver, and Type of connection must be specified when you + * open the socket. + * + * The parameters to tou_socket, therefore mean something! + * some extra checking has been put in to try and catch bad usage. */ /* creation/connections */ @@ -87,6 +111,12 @@ int tou_connect(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen, uint32_t conn_period); int tou_accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); + /* for relay connections */ +int tou_connect_via_relay(int sockfd, + const struct sockaddr_in *own_addr, + const struct sockaddr_in *proxy_addr, + const struct sockaddr_in *dest_addr); + /* non-standard bonuses */ int tou_connected(int sockfd); int tou_listenfor(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen); diff --git a/libretroshare/src/tcponudp/udprelay.cc b/libretroshare/src/tcponudp/udprelay.cc index f7bea71f5..2a6705c02 100644 --- a/libretroshare/src/tcponudp/udprelay.cc +++ b/libretroshare/src/tcponudp/udprelay.cc @@ -62,7 +62,7 @@ UdpRelayReceiver::~UdpRelayReceiver() } -int UdpRelayReceiver::addUdpPeer(UdpPeer *peer, UdpRelayAddrSet *endPoints, const struct sockaddr_in &proxyaddr) +int UdpRelayReceiver::addUdpPeer(UdpPeer *peer, UdpRelayAddrSet *endPoints, const struct sockaddr_in *proxyaddr) { RsStackMutex stack(peerMtx); /********** LOCK MUTEX *********/ @@ -81,7 +81,7 @@ int UdpRelayReceiver::addUdpPeer(UdpPeer *peer, UdpRelayAddrSet *endPoints, } /* setup a peer */ - UdpRelayEnd ure(peer, endPoints, &proxyaddr); + UdpRelayEnd ure(peer, endPoints, proxyaddr); mStreams[realPeerAddr] = ure; @@ -628,3 +628,120 @@ int createRelayUdpPacket(const void *data, const int size, void *newpkt, int new return pktsize; } + + +/******* Small Container Class Helper Functions ****/ + +UdpRelayAddrSet::UdpRelayAddrSet() +{ + sockaddr_clear(&mSrcAddr); + sockaddr_clear(&mDestAddr); +} + +UdpRelayAddrSet::UdpRelayAddrSet(const sockaddr_in *ownAddr, const sockaddr_in *destAddr) +{ + mSrcAddr = *ownAddr; + mDestAddr = *destAddr; +} + +UdpRelayAddrSet UdpRelayAddrSet::flippedSet() +{ + UdpRelayAddrSet flipped(&mDestAddr, &mSrcAddr); + return flipped; +} + + +int operator<(const UdpRelayAddrSet &a, const UdpRelayAddrSet &b) +{ + if (a.mSrcAddr < b.mSrcAddr) + { + return 1; + } + + if (a.mSrcAddr == b.mSrcAddr) + { + if (a.mDestAddr < b.mDestAddr) + { + return 1; + } + } + return 0; +} + + +UdpRelayProxy::UdpRelayProxy() +{ + mBandwidth = 0; + mDataSize = 0; + mLastBandwidthTS = 0; + mLastTS = 0; + mRelayClass = 0; +} + +UdpRelayProxy::UdpRelayProxy(UdpRelayAddrSet *addrSet, int relayClass) +{ + mAddrs = *addrSet; + mRelayClass = relayClass; + + mBandwidth = 0; + mDataSize = 0; + mLastBandwidthTS = 0; + mLastTS = 0; +} + +UdpRelayEnd::UdpRelayEnd() +{ + sockaddr_clear(&mLocalAddr); + sockaddr_clear(&mProxyAddr); + sockaddr_clear(&mRemoteAddr); + + mPeer = NULL; +} + +UdpRelayEnd::UdpRelayEnd(UdpPeer *peer, UdpRelayAddrSet *endPoints, const struct sockaddr_in *proxyaddr) +{ + mPeer = peer; + mLocalAddr = endPoints->mSrcAddr; + mRemoteAddr = endPoints->mDestAddr; + mProxyAddr = *proxyaddr; +} + + + + + +std::ostream &operator<<(std::ostream &out, const UdpRelayAddrSet &uras) +{ + out << "<" << uras.mSrcAddr << "," << uras.mDestAddr << ">"; + return out; +} + +std::ostream &operator<<(std::ostream &out, const UdpRelayProxy &urp) +{ + time_t now = time(NULL); + out << "UdpRelayProxy for " << urp.mAddrs; + out << std::endl; + out << "\tRelayClass: " << urp.mRelayClass; + out << std::endl; + out << "\tBandwidth: " << urp.mBandwidth; + out << std::endl; + out << "\tDataSize: " << urp.mDataSize; + out << std::endl; + out << "\tLastBandwidthTS: " << now - urp.mLastBandwidthTS << " secs ago"; + out << std::endl; + out << "\tLastTS: " << now - urp.mLastTS << " secs ago"; + out << std::endl; + + return out; +} + +std::ostream &operator<<(std::ostream &out, const UdpRelayEnd &ure) +{ + out << "UdpRelayEnd: <" << ure.mLocalAddr << " => " << ure.mProxyAddr << " <= "; + out << ure.mRemoteAddr << ">"; + return out; +} + + + + diff --git a/libretroshare/src/tcponudp/udprelay.h b/libretroshare/src/tcponudp/udprelay.h index c0df784f6..80e810d59 100644 --- a/libretroshare/src/tcponudp/udprelay.h +++ b/libretroshare/src/tcponudp/udprelay.h @@ -35,6 +35,7 @@ class UdpRelayAddrSet { public: UdpRelayAddrSet(); + UdpRelayAddrSet(const sockaddr_in *ownAddr, const sockaddr_in *destAddr); UdpRelayAddrSet flippedSet(); @@ -64,7 +65,7 @@ class UdpRelayEnd { public: - UdpRelayEnd() { return; } + UdpRelayEnd(); UdpRelayEnd(UdpPeer *peer, UdpRelayAddrSet *endPoints, const struct sockaddr_in *proxyaddr); struct sockaddr_in mLocalAddr; @@ -111,7 +112,7 @@ class UdpRelayReceiver: public UdpSubReceiver virtual ~UdpRelayReceiver(); /* add a TCPonUDP stream (ENDs) */ -int addUdpPeer(UdpPeer *peer, UdpRelayAddrSet *endPoints, const struct sockaddr_in &proxyaddr); +int addUdpPeer(UdpPeer *peer, UdpRelayAddrSet *endPoints, const struct sockaddr_in *proxyaddr); int removeUdpPeer(UdpPeer *peer); /* add a Relay Point (for the Relay).