* 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
This commit is contained in:
drbob 2011-07-21 11:28:19 +00:00
parent f6002b3981
commit b56ddfeb5b
10 changed files with 445 additions and 11 deletions

View File

@ -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);
}

View File

@ -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?
*/

View File

@ -1304,6 +1304,23 @@ bool p3NetMgrIMPL::netAssistFriend(std::string id, bool on)
}
bool p3NetMgrIMPL::netAssistAttach(bool on)
{
std::map<uint32_t, pqiNetAssistConnect *>::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);
}
}
}

View File

@ -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();

View File

@ -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;

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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 <iostream>
#include <stdlib.h>
// 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 <unistd.h>
#include <fcntl.h>
#include <errno.h>
/*
* 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] <laddr> <lport> ";
std::cerr << " <raddr> <rport> ";
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;
}

View File

@ -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