From b56ddfeb5b03463088b0abcabd921a7634b32e81 Mon Sep 17 00:00:00 2001 From: drbob Date: Thu, 21 Jul 2011 11:28:19 +0000 Subject: [PATCH] * Switched on Dht "Attach" Mode if RS is firewalled. (and not nice firewall). * Added interfaces to enable AttachMode switch. * Added further tcponudp tests. git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@4484 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/dht/p3bitdht.cc | 14 + libretroshare/src/dht/p3bitdht.h | 5 + libretroshare/src/pqi/p3netmgr.cc | 50 +++ libretroshare/src/pqi/p3netmgr.h | 3 +- libretroshare/src/pqi/pqiassist.h | 3 + .../src/tests/scripts/config-macosx.mk | 13 +- libretroshare/src/tests/tcponudp/Makefile | 8 +- .../src/tests/tcponudp/stacks_tou.sh | 2 +- libretroshare/src/tests/tcponudp/timed_tou.cc | 338 ++++++++++++++++++ libretroshare/src/tests/tcponudp/timed_tou.sh | 20 ++ 10 files changed, 445 insertions(+), 11 deletions(-) create mode 100644 libretroshare/src/tests/tcponudp/timed_tou.cc create mode 100755 libretroshare/src/tests/tcponudp/timed_tou.sh diff --git a/libretroshare/src/dht/p3bitdht.cc b/libretroshare/src/dht/p3bitdht.cc index dd1059d0d..70bf9be46 100644 --- a/libretroshare/src/dht/p3bitdht.cc +++ b/libretroshare/src/dht/p3bitdht.cc @@ -319,3 +319,17 @@ bool p3BitDht::getExternalInterface(struct sockaddr_in &raddr, } +bool p3BitDht::setAttachMode(bool on) +{ + +#ifdef DEBUG_BITDHT + std::cerr << "p3BitDht::setAttachMode(" << on << ")"; + std::cerr << std::endl; +#endif + + return mUdpBitDht->setAttachMode(on); +} + + + + diff --git a/libretroshare/src/dht/p3bitdht.h b/libretroshare/src/dht/p3bitdht.h index 02994c032..658e9f238 100644 --- a/libretroshare/src/dht/p3bitdht.h +++ b/libretroshare/src/dht/p3bitdht.h @@ -192,6 +192,11 @@ virtual bool getPeerStatus(std::string id, virtual bool getExternalInterface(struct sockaddr_in &raddr, uint32_t &mode); + +virtual bool setAttachMode(bool on); + + + /* notifyPeer/setExtInterface/Bootstrap/Stun * hould all be removed from NetAssist? */ diff --git a/libretroshare/src/pqi/p3netmgr.cc b/libretroshare/src/pqi/p3netmgr.cc index c6bfbb432..363bf285f 100644 --- a/libretroshare/src/pqi/p3netmgr.cc +++ b/libretroshare/src/pqi/p3netmgr.cc @@ -1304,6 +1304,23 @@ bool p3NetMgrIMPL::netAssistFriend(std::string id, bool on) } +bool p3NetMgrIMPL::netAssistAttach(bool on) +{ + std::map::iterator it; + +#ifdef NETMGR_DEBUG + std::cerr << "p3NetMgrIMPL::netAssistAttach(" << on << ")"; + std::cerr << std::endl; +#endif + + for(it = mDhts.begin(); it != mDhts.end(); it++) + { + (it->second)->setAttachMode(on); + } + return true; +} + + bool p3NetMgrIMPL::netAssistStatusUpdate(std::string id, int state) { @@ -1622,12 +1639,45 @@ void p3NetMgrIMPL::updateNatSetting() case RSNET_NATTYPE_NONE: case RSNET_NATTYPE_UNKNOWN: case RSNET_NATTYPE_SYMMETRIC: + case RSNET_NATTYPE_DETERM_SYM: case RSNET_NATTYPE_FULL_CONE: case RSNET_NATTYPE_OTHER: mProxyStunner->setRefreshPeriod(NET_STUNNER_PERIOD_SLOW); break; } + + + /* This controls the Attach mode of the DHT... + * which effectively makes the DHT "attach" to Open Nodes. + * So that messages can get through. + * We only want to be attached - if we don't have a stable DHT port. + */ + if ((natHole == RSNET_NATHOLE_NONE) || (natHole == RSNET_NATHOLE_UNKNOWN)) + { + switch(natType) + { + /* switch to attach mode if we have a bad firewall */ + case RSNET_NATTYPE_UNKNOWN: + case RSNET_NATTYPE_SYMMETRIC: + case RSNET_NATTYPE_RESTRICTED_CONE: + case RSNET_NATTYPE_DETERM_SYM: + case RSNET_NATTYPE_OTHER: + netAssistAttach(true); + + break; + /* switch off attach mode if we have a nice firewall */ + case RSNET_NATTYPE_NONE: + case RSNET_NATTYPE_FULL_CONE: + netAssistAttach(false); + break; + } + } + else + { + // Switch off Firewall Mode (Attach) + netAssistAttach(false); + } } } diff --git a/libretroshare/src/pqi/p3netmgr.h b/libretroshare/src/pqi/p3netmgr.h index 8ba7ccee5..23eb4f088 100644 --- a/libretroshare/src/pqi/p3netmgr.h +++ b/libretroshare/src/pqi/p3netmgr.h @@ -254,7 +254,6 @@ bool netAssistConnectActive(); bool netAssistConnectShutdown(); bool netAssistConnectStats(uint32_t &netsize, uint32_t &localnetsize); void netAssistConnectTick(); - /* Assist Firewall */ bool netAssistExtAddress(struct sockaddr_in &extAddr); bool netAssistFirewallPorts(uint16_t iport, uint16_t eport); @@ -265,6 +264,8 @@ bool netAssistSetAddress( struct sockaddr_in &laddr, struct sockaddr_in &eaddr, uint32_t mode); +bool netAssistAttach(bool on); + /* Internal Functions */ void netReset(); diff --git a/libretroshare/src/pqi/pqiassist.h b/libretroshare/src/pqi/pqiassist.h index ae500ba94..5586642ea 100644 --- a/libretroshare/src/pqi/pqiassist.h +++ b/libretroshare/src/pqi/pqiassist.h @@ -132,6 +132,9 @@ virtual bool getPeerStatus(std::string id, struct sockaddr_in &laddr, struct sockaddr_in &raddr, uint32_t &type, uint32_t &mode) = 0; +virtual bool setAttachMode(bool on) = 0; + + //virtual bool getExternalInterface(struct sockaddr_in &raddr, // uint32_t &mode) = 0; diff --git a/libretroshare/src/tests/scripts/config-macosx.mk b/libretroshare/src/tests/scripts/config-macosx.mk index 6b5fa8c66..3f122a3ea 100644 --- a/libretroshare/src/tests/scripts/config-macosx.mk +++ b/libretroshare/src/tests/scripts/config-macosx.mk @@ -40,6 +40,7 @@ RANLIB = ranlib # Dummy ranlib -> can't do it until afterwards with universal binaries. # RANLIB = ls -l +BITDIR = $(DHT_TOP_DIR)/lib LIBDIR = $(RS_TOP_DIR)/lib LIBRS = $(LIBDIR)/libretroshare.a @@ -82,16 +83,14 @@ LIBS = -Wl,-search_paths_first # LIBS += -arch ppc -arch i386 #LIBS += -Wl,-syslibroot,/Developer/SDKs/MacOSX10.5u.sdk -LIBS += -L$(LIBDIR) -lretroshare +LIBS = -lgpgme -L$(LIBDIR) -lretroshare +LIBS += -L$(BITDIR) -lbitdht ifdef PQI_USE_XPGP - LIBS += -L$(SSL_DIR) + LIBS += -L$(SSL_DIR) endif LIBS += -lssl -lcrypto -lpthread -LIBS += -L$(OPT_LIBS) -LIBS += -lgpgme -lgpg-error LIBS += -L$(UPNPC_DIR) -lminiupnpc -LIBS += $(XLIB) -ldl -lz - -RSLIBS = $(LIBS) +LIBS += $(XLIB) -ldl -lz + diff --git a/libretroshare/src/tests/tcponudp/Makefile b/libretroshare/src/tests/tcponudp/Makefile index f374b4776..9d71743b7 100644 --- a/libretroshare/src/tests/tcponudp/Makefile +++ b/libretroshare/src/tests/tcponudp/Makefile @@ -16,17 +16,18 @@ include $(RS_TOP_DIR)/tests/scripts/config.mk OBJ = udptestfn.o EXECS = udpsock_test udpsort_test udp_server test_tou -EXECS += pair_tou stacks_tou bidir_tou +EXECS += pair_tou stacks_tou bidir_tou timed_tou #pair_tou reset_tou internal_tou largefile_tou TESTOBJ = udpsock_test.o udpsort_test.o udp_server.o test_tou.o TESTOBJ += pair_tou.o udptestfn.o +TESTOBJ += stacks_tou.o bidir_tou.o timed_tou.o #TESTOBJ += pair_tou.o reset_tou.o largefile_tou.o #internal_tou.o TESTS = udpsock_test udpsort_test udp_server test_tou -TESTS += stacks_tou bidir_tou +TESTS += stacks_tou bidir_tou timed_tou #TESTS += pair_tou # Unfortunately the design of tou has changed over time. # and these tests cannot be performed at the moment. @@ -56,6 +57,9 @@ stacks_tou : $(OBJ) stacks_tou.o bidir_tou : $(OBJ) bidir_tou.o $(CC) $(CFLAGS) -o bidir_tou bidir_tou.o $(OBJ) $(LIBS) +timed_tou : $(OBJ) timed_tou.o + $(CC) $(CFLAGS) -o timed_tou timed_tou.o $(OBJ) $(LIBS) + reset_tou : $(OBJ) reset_tou.o $(CC) $(CFLAGS) -o reset_tou reset_tou.o $(OBJ) $(LIBS) diff --git a/libretroshare/src/tests/tcponudp/stacks_tou.sh b/libretroshare/src/tests/tcponudp/stacks_tou.sh index 07dc55015..eaaf794ae 100755 --- a/libretroshare/src/tests/tcponudp/stacks_tou.sh +++ b/libretroshare/src/tests/tcponudp/stacks_tou.sh @@ -2,7 +2,7 @@ # Script to Test the udp_server code. EXEC=./stacks_tou -DATAFILE=../../lib/libretroshare.a +DATAFILE=./stacks_tou TMPOUTPUT=tmpoutput$$ EXPECTEDPERIOD=10 diff --git a/libretroshare/src/tests/tcponudp/timed_tou.cc b/libretroshare/src/tests/tcponudp/timed_tou.cc new file mode 100644 index 000000000..c87917c60 --- /dev/null +++ b/libretroshare/src/tests/tcponudp/timed_tou.cc @@ -0,0 +1,338 @@ +/* + * "$Id: pair_tou.cc,v 1.3 2007-02-18 21:46:50 rmf24 Exp $" + * + * TCP-on-UDP (tou) network interface for RetroShare. + * + * Copyright 2004-2006 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + + + + +#include +#include + +// for printing sockaddr +#include "udp/udpstack.h" + +#include "tcponudp/tou.h" +#include "tcponudp/udppeer.h" +#include "tcponudp/udprelay.h" + +#include "util/bdnet.h" + +#include "util/rsrandom.h" + +#include +#include +#include + + +/* + * This test creates the same stacks as are used in RS. + * This additionally tests the "checkFns" for the other UdpReceivers, which could potentially be modifying the data. + * obviously they shouldn't! + * + */ + +void usage(char *name) +{ + std::cerr << "Usage: " << name; + std::cerr << " [-pco] "; + std::cerr << " "; + std::cerr << std::endl; + exit(1); + return; +} + +int main(int argc, char **argv) +{ + int c; + bool isProxy = false; + bool toConnect = false; + bool stayOpen = false; + + int totalwbytes = 0; + int totalmbytes = 0; + int totalrbytes = 0; + + while(-1 != (c = getopt(argc, argv, "pco"))) + { + switch (c) + { + case 'p': + isProxy = true; + break; + case 'c': + toConnect = true; + break; + case 'o': + stayOpen = true; + break; + default: + usage(argv[0]); + break; + } + } + + if (argc-optind < 4) + { + usage(argv[0]); + return 1; + } + + /* setup the local/remote addresses. + */ + struct sockaddr_in laddr; + struct sockaddr_in raddr; + + laddr.sin_family = AF_INET; + raddr.sin_family = AF_INET; + + if ((!bdnet_inet_aton(argv[optind], &(laddr.sin_addr))) || + (!bdnet_inet_aton(argv[optind+2], &(raddr.sin_addr)))) + { + std::cerr << "Invalid addresses!" << std::endl; + usage(argv[0]); + } + + laddr.sin_port = htons(atoi(argv[optind+1])); + raddr.sin_port = htons(atoi(argv[optind+3])); + + std::cerr << "Local Address: " << laddr << std::endl; + std::cerr << "Remote Address: " << raddr << std::endl; + + std::cerr << "Creating with Lossy Udp Layers for further testing"; + std::cerr << std::endl; + + UdpStack *udpStack1 = new UdpStack(UDP_TEST_TIMED_LAYER,laddr); + sleep(1); + UdpStack *udpStack2 = new UdpStack(UDP_TEST_TIMED_LAYER,raddr); + + UdpSubReceiver *udpReceivers[4]; + int udpTypes[4]; + + // NOTE DHT is too hard to add at the moment. + + UdpRelayReceiver *mRelay1 = new UdpRelayReceiver(udpStack1); + udpReceivers[1] = mRelay1; + udpTypes[1] = TOU_RECEIVER_TYPE_UDPRELAY; + udpStack1->addReceiver(udpReceivers[1]); + + udpReceivers[0] = new UdpPeerReceiver(udpStack1); + udpTypes[0] = TOU_RECEIVER_TYPE_UDPPEER; + udpStack1->addReceiver(udpReceivers[0]); + + // STACK 2. + UdpRelayReceiver *mRelay2 = new UdpRelayReceiver(udpStack2); + udpReceivers[3] = mRelay2; + udpTypes[3] = TOU_RECEIVER_TYPE_UDPRELAY; + udpStack2->addReceiver(udpReceivers[3]); + + udpReceivers[2] = new UdpPeerReceiver(udpStack2); + udpTypes[2] = TOU_RECEIVER_TYPE_UDPPEER; + udpStack2->addReceiver(udpReceivers[2]); + + tou_init((void **) udpReceivers, udpTypes, 4); + + + int sockfd = tou_socket(0, TOU_RECEIVER_TYPE_UDPPEER, 0); + int sockfd2 = tou_socket(2, TOU_RECEIVER_TYPE_UDPPEER, 0); + if ((sockfd <= 0) || (sockfd2 <= 0)) + { + std::cerr << "Failed to open socket!: "; + std::cerr << "Socket Error:" << tou_errno(sockfd) << std::endl; + std::cerr << "Socket Error:" << tou_errno(sockfd2) << std::endl; + return -1; + } + std::cerr << "Sockets Created: " << sockfd << " & " << sockfd2 << std::endl; + + std::cerr << "Socket Non-Blocking" << std::endl; + + std::cerr << "Socket1 Bound to: " << laddr << std::endl; + std::cerr << "Socket2 Bound to: " << raddr << std::endl; + + int err = 0; + + std::cerr << "Socket1 Connecting to: " << raddr << std::endl; + err = tou_connect(sockfd, (struct sockaddr *) &raddr, sizeof(raddr), 30); + + std::cerr << "Socket2 Connecting to: " << raddr << std::endl; + err = tou_connect(sockfd2, (struct sockaddr *) &laddr, sizeof(laddr), 30); + + while((!tou_connected(sockfd)) && (!tou_connected(sockfd2))) + { + usleep(100000); + std::cerr << "."; + } + + std::cerr << "Socket Connected" << std::endl; + +#define MAX_READ 20000 + + /* send data */ + int bufsize = MAX_READ; + char buffer[MAX_READ]; + char middata[MAX_READ]; + char data[MAX_READ]; + int readsize = 0; + int midsize = 0; + + bdnet_fcntl(0, F_SETFL, O_NONBLOCK); + bdnet_fcntl(1,F_SETFL,O_NONBLOCK); + + time_t lastRead = time(NULL); + bool doneWrite = false; + bool doneRead = false; + bool blockread = false; + bool blockmid = false; + + while((!doneWrite) || (!doneRead)) + { + /* read -> write_socket... */ + usleep(10); + + if (blockread != true) + { + int readbuf = 1 + RSRandom::random_u32() % (MAX_READ - 1); + readsize = read(0, buffer, readbuf); + if (readsize) + { + //std::cerr << "read " << readsize << " / " << readbuf; + //std::cerr << std::endl; + } + } + if ((readsize == 0) && (!doneWrite)) + { + /* eof */ + doneWrite = true; + std::cerr << "Write Done Total: " << totalwbytes; + std::cerr << std::endl; + } + /* now we write */ + if ((readsize > 0) && (-1 == tou_write(sockfd, buffer, readsize))) + { + //std::cerr << "Blocked Write "; + //std::cerr << "Error: " << tou_errno(sockfd); + //std::cerr << std::endl; + blockread = true; + } + else + { + blockread = false; + totalwbytes += readsize; + + if (readsize) + { + std::cerr << "Written: " << readsize << ", Total: " << totalwbytes; + std::cerr << " Total In Transit: " << totalwbytes - totalrbytes; + std::cerr << std::endl; + } + } + + /*************** Here we read it in, and send it back out... + * so the data is flowing both ways through the UDP connection + * + *****/ + + + if (!blockmid) + { + /* read from socket 2, and write back to socket 2 */ + + int readmidbuf = 1 + RSRandom::random_u32() % (MAX_READ - 1); + if (0 < (midsize = tou_read(sockfd2, middata, readmidbuf))) + { + //std::cerr << "MidRead: " << mid << " Total: " << totalrbytes; + //std::cerr << " In Transit: " << totalwbytes - totalrbytes; + //std::cerr << std::endl; + } + } + + /* now we write */ + if ((midsize > 0) && (-1 == tou_write(sockfd2, middata, midsize))) + { + //std::cerr << "Blocked Write "; + //std::cerr << "Error: " << tou_errno(sockfd); + //std::cerr << std::endl; + blockmid = true; + } + else + { + blockmid = false; + + if (midsize > 0) + { + totalmbytes += midsize; + + std::cerr << "MidRead: " << midsize << ", Total: " << totalmbytes; + std::cerr << " => Transit => : " << totalwbytes - totalmbytes; + std::cerr << " <= Transit <= : " << totalmbytes - totalrbytes; + std::cerr << std::endl; + } + } + + /***** READ FROM FIRST SOCKET *****/ + + int ret = 0; + int readbuf2 = 1 + RSRandom::random_u32() % (MAX_READ - 1); + if (0 < (ret = tou_read(sockfd, data, readbuf2))) + { + //std::cerr << "TF(" << ret << ")" << std::endl; + write(1, data, ret); + totalrbytes += ret; + + std::cerr << "Read: " << ret << " Total: " << totalrbytes; + std::cerr << " Total In Transit: " << totalwbytes - totalrbytes; + std::cerr << std::endl; + + lastRead = time(NULL); + } + else if ((ret == 0) && (!doneRead)) + { + doneRead = true; + std::cerr << "Read Done Total: " << totalrbytes; + std::cerr << std::endl; + } + else + { + //std::cerr << "Blocked Read: " << "Error: " << tou_errno(sockfd); + //std::cerr << std::endl; +#define TIMEOUT 15 + if ((!doneRead) && (time(NULL) - lastRead > TIMEOUT)) + { + doneRead = true; + std::cerr << "TIMEOUT: Read Done Total: " << totalrbytes; + std::cerr << std::endl; + } + } + + + } + + /* this is blocking??? */ + tou_close(sockfd); + tou_close(sockfd2); + + std::cerr << "Transfer Complete: " << totalwbytes << " bytes"; + std::cerr << std::endl; + return 1; +} + diff --git a/libretroshare/src/tests/tcponudp/timed_tou.sh b/libretroshare/src/tests/tcponudp/timed_tou.sh new file mode 100755 index 000000000..d8bbffe8e --- /dev/null +++ b/libretroshare/src/tests/tcponudp/timed_tou.sh @@ -0,0 +1,20 @@ +#/bin/sh +# Script to Test the udp_server code. + +EXEC=./timed_tou +DATAFILE=./timed_tou + +TMPOUTPUT=tmpoutput$$ +EXPECTEDPERIOD=10 + +$EXEC 127.0.0.1 4401 127.0.0.1 4032 < $DATAFILE > $TMPOUTPUT + +if diff -s $DATAFILE $TMPOUTPUT +then + echo "SUCCESS" +else + echo "FAILURE to accurately transfer DATA" +fi + +rm $TMPOUTPUT +