mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-05-02 06:06:10 -04:00
Changes to integrate bitdht into libretroshare.
Mainly re-organising tcponudp... tests->test area network->trash (uses libbitdht classes). new udp interfaces (udppeer + udpstunner) Changes include: * p3bitdht: added "addReceiver() call, and more debugging. * p3bitdht: added DO_IDLE flag so searches are continous. * p3bitdht/pqiassist: matched up Assist interface. * fixed pqiNetListener interface. * rsinit/p3connmgr: setup udp init * tcpstream: switched to new udp receiver. * added "blogs" switch in libretroshare.pro (was stopping compiling ;) * added "bitdht" switch in libretroshare.pro git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@3323 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
parent
c1b624832f
commit
fcdd7ee113
34 changed files with 627 additions and 1770 deletions
|
@ -1,60 +0,0 @@
|
|||
|
||||
RS_TOP_DIR = ..
|
||||
##### Define any flags that are needed for this section #######
|
||||
###############################################################
|
||||
|
||||
###############################################################
|
||||
include $(RS_TOP_DIR)/scripts/config.mk
|
||||
###############################################################
|
||||
|
||||
BIOOBJ = bss_tou.o
|
||||
|
||||
RSOBJ = tou_net.o udplayer.o udpsorter.o udptestfn.o extaddrfinder.o
|
||||
RSOBJ += tcppacket.o tcpstream.o tou.o $(BIOOBJ)
|
||||
|
||||
EXECS = librs udpsock_test udpsort_test udp_server
|
||||
#test_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 reset_tou.o largefile_tou.o
|
||||
#internal_tou.o
|
||||
|
||||
TESTS = udpsock_test udpsort_test udp_server test_tou
|
||||
TESTS += pair_tou reset_tou largefile_tou
|
||||
#internal_tou
|
||||
|
||||
all: librs tests
|
||||
|
||||
udpsock_test : $(OBJ) udpsock_test.o
|
||||
$(CC) $(CFLAGS) -o udpsock_test udpsock_test.o $(OBJ) $(LIBS)
|
||||
|
||||
udpsort_test : $(OBJ) udpsort_test.o
|
||||
$(CC) $(CFLAGS) -o udpsort_test udpsort_test.o $(OBJ) $(LIBS)
|
||||
|
||||
udp_server: $(OBJ) udp_server.o
|
||||
$(CC) $(CFLAGS) -o udp_server udp_server.o $(OBJ) $(LIBS)
|
||||
|
||||
test_tou : $(OBJ) test_tou.o
|
||||
$(CC) $(CFLAGS) -o test_tou test_tou.o $(OBJ) $(LIBS)
|
||||
|
||||
pair_tou : $(OBJ) pair_tou.o
|
||||
$(CC) $(CFLAGS) -o pair_tou pair_tou.o $(OBJ) $(LIBS)
|
||||
|
||||
reset_tou : $(OBJ) reset_tou.o
|
||||
$(CC) $(CFLAGS) -o reset_tou reset_tou.o $(OBJ) $(LIBS)
|
||||
|
||||
internal_tou : $(OBJ) internal_tou.o
|
||||
$(CC) $(CFLAGS) -o internal_tou internal_tou.o $(OBJ) $(LIBS)
|
||||
|
||||
largefile_tou : $(OBJ) largefile_tou.o
|
||||
$(CC) $(CFLAGS) -o largefile_tou largefile_tou.o $(OBJ) $(LIBS)
|
||||
|
||||
|
||||
# Extra Rule for BIOFLAGS
|
||||
.c.o:
|
||||
$(BIOCC) $(BIOCFLAGS) -c $<
|
||||
|
||||
###############################################################
|
||||
include $(RS_TOP_DIR)/scripts/rules.mk
|
||||
###############################################################
|
||||
|
|
@ -1,632 +0,0 @@
|
|||
/*
|
||||
* "$Id: internal_tou.cc,v 1.2 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".
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/**********************************************************
|
||||
* There appears (was) to be an elusive bug in the tou internals.
|
||||
* most likely to be in the packing and unpacking of the
|
||||
* data queues.
|
||||
*
|
||||
* This test is designed to load the queues up and then
|
||||
* transfer the data, repeatly with different size packets.
|
||||
*
|
||||
* to do this effectively we need to access the TcpStream
|
||||
* objects, instead of the tou.h interface.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
|
||||
// for printing sockaddr
|
||||
#include "udplayer.h"
|
||||
#include "tcpstream.h"
|
||||
|
||||
#include "tou.h"
|
||||
#include "tou_net.h"
|
||||
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
|
||||
/* This is a simple test to ensure that the tou behaviour
|
||||
* is almost identical to a standard tcp socket.
|
||||
*
|
||||
* In this version we open 2 sockets, and attempt to
|
||||
* communicate with ourselves....
|
||||
*
|
||||
*/
|
||||
|
||||
int setup_socket(struct sockaddr_in addr);
|
||||
int connect_socket_pair(int fd1, int fd2,
|
||||
struct sockaddr_in addr1, struct sockaddr_in addr2);
|
||||
int send_data_via_pair(int sockfd1, int sockfd2, char *data, int size);
|
||||
|
||||
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 i,j;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// tounet_init();
|
||||
|
||||
|
||||
/* setup the local/remote addresses.
|
||||
*/
|
||||
struct sockaddr_in laddr;
|
||||
struct sockaddr_in raddr;
|
||||
|
||||
laddr.sin_family = AF_INET;
|
||||
raddr.sin_family = AF_INET;
|
||||
|
||||
if ((!tounet_inet_aton(argv[optind], &(laddr.sin_addr))) ||
|
||||
(!tounet_inet_aton(argv[optind+2], &(raddr.sin_addr))))
|
||||
{
|
||||
std::cerr << "Invalid addresses!" << std::endl;
|
||||
usage(argv[0]);
|
||||
}
|
||||
|
||||
unsigned short laddr_port = atoi(argv[optind+1]);
|
||||
unsigned short raddr_port = atoi(argv[optind+3]);
|
||||
|
||||
laddr.sin_port = htons(laddr_port);
|
||||
raddr.sin_port = htons(raddr_port);
|
||||
|
||||
/* so create the Udp/Tcp components */
|
||||
//UdpLayer udp1(laddr);
|
||||
//UdpLayer udp2(raddr);
|
||||
LossyUdpLayer udp1(laddr, 0.10);
|
||||
LossyUdpLayer udp2(raddr, 0.10);
|
||||
|
||||
/* check that they are okay */
|
||||
if ((!udp1.okay()) || (!udp2.okay()))
|
||||
{
|
||||
std::cerr << "Trouble opening udp ports!";
|
||||
std::cerr << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
TcpStream tcp1(&udp1);
|
||||
TcpStream tcp2(&udp2);
|
||||
|
||||
udp1.setRemoteAddr(raddr);
|
||||
udp2.setRemoteAddr(laddr);
|
||||
tcp1.connect(); // start the connection.
|
||||
|
||||
/* now connect them */
|
||||
while ((!tcp1.isConnected()) || (!tcp2.isConnected()))
|
||||
{
|
||||
usleep(10000); /* 10 ms */
|
||||
tcp1.tick();
|
||||
tcp2.tick();
|
||||
}
|
||||
|
||||
std::cerr << "Connection Established!" << std::endl;
|
||||
|
||||
for(i = 0; i < 10; i++)
|
||||
{
|
||||
|
||||
int size = 1024000;
|
||||
char rnddata1[size];
|
||||
char rnddata2[size];
|
||||
|
||||
for(j = 0; j < size; j++)
|
||||
{
|
||||
rnddata1[j] = (unsigned char) (255.0 *
|
||||
rand() / (RAND_MAX + 1.0));
|
||||
|
||||
rnddata2[j] = (unsigned char) (255.0 *
|
||||
rand() / (RAND_MAX + 1.0));
|
||||
}
|
||||
|
||||
/* for each iteration, we want to
|
||||
* (1) fill up the outgoing buffers with stuff
|
||||
*/
|
||||
|
||||
int sent1 = 0;
|
||||
int sent2 = 0;
|
||||
int fill1, fill2;
|
||||
int MaxSend = 1000000;
|
||||
|
||||
while((fill1 = tcp1.write_allowed()) && (sent1 < MaxSend))
|
||||
{
|
||||
/* fill with a random little bit more */
|
||||
int psize = (int) ((i + 1.0) * 255.0 *
|
||||
rand() / (RAND_MAX + 1.0));
|
||||
|
||||
/* don't overload */
|
||||
if (psize > fill1)
|
||||
{
|
||||
std::cerr << "LAST FILL1" << std::endl;
|
||||
psize = fill1;
|
||||
}
|
||||
|
||||
int ret = tcp1.write(&(rnddata1[sent1]), psize);
|
||||
|
||||
if (ret)
|
||||
{
|
||||
sent1 += ret;
|
||||
std::cerr << "Filled tcp1 with " << ret << " more bytes, total:";
|
||||
std::cerr << sent1 << " was allowed: " << fill1;
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
|
||||
//tcp1.status(std::cerr);
|
||||
|
||||
}
|
||||
std::cerr << "Tcp1 full with " << sent1 << " bytes ";
|
||||
std::cerr << std::endl;
|
||||
|
||||
while((fill2 = tcp2.write_allowed()) && (sent2 < MaxSend))
|
||||
{
|
||||
/* fill with a random little bit more */
|
||||
/* slightly larger sizes */
|
||||
int psize = (int) ((i + 1.0) * 1255.0 *
|
||||
rand() / (RAND_MAX + 1.0));
|
||||
|
||||
/* don't overload */
|
||||
if (psize > fill2)
|
||||
{
|
||||
std::cerr << "LAST FILL2" << std::endl;
|
||||
psize = fill2;
|
||||
}
|
||||
|
||||
int ret = tcp2.write(&(rnddata2[sent2]), psize);
|
||||
|
||||
if (ret)
|
||||
{
|
||||
sent2 += ret;
|
||||
std::cerr << "Filled tcp2 with " << ret << " more bytes, total:";
|
||||
std::cerr << sent2 << " was allowed: " << fill2;
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
|
||||
//tcp2.status(std::cerr);
|
||||
|
||||
}
|
||||
std::cerr << "Tcp2 full with " << sent2 << " bytes ";
|
||||
std::cerr << std::endl;
|
||||
|
||||
/* for every second iteration, fill up the read buffer before starting */
|
||||
if (i % 2 == 0)
|
||||
{
|
||||
for(j = 0; j < 100; j++)
|
||||
{
|
||||
tcp1.tick();
|
||||
tcp2.tick();
|
||||
}
|
||||
}
|
||||
|
||||
/* now we read/tick and empty */
|
||||
int read1 = 0;
|
||||
int read2 = 0;
|
||||
|
||||
while(read1 < sent2)
|
||||
{
|
||||
tcp1.tick();
|
||||
tcp2.tick();
|
||||
|
||||
/* fill with a random little bit more */
|
||||
/* This one has a small read, while tcp2 has a large read */
|
||||
int psize = (int) ((i + 1.0) * 100.0 *
|
||||
rand() / (RAND_MAX + 1.0));
|
||||
|
||||
/* limit to what we have! */
|
||||
if (psize > sent2 - read1)
|
||||
{
|
||||
std::cerr << "LAST READ1" << std::endl;
|
||||
psize = sent2 - read1;
|
||||
}
|
||||
|
||||
char rbuf[psize];
|
||||
int rsize = psize;
|
||||
|
||||
int ret = tcp1.read(rbuf, rsize);
|
||||
if (0 < ret)
|
||||
{
|
||||
/* check the data */
|
||||
for(j = 0; j < ret; j++)
|
||||
{
|
||||
if (rnddata2[read1 + j] != rbuf[j])
|
||||
{
|
||||
std::cerr << "Error Data Mismatch @ read1:" << read1;
|
||||
std::cerr << " + j:" << j << " rsize: " << rsize;
|
||||
std::cerr << " Index: " << read1 + j;
|
||||
std::cerr << std::endl;
|
||||
|
||||
int badoffset = read1 + j;
|
||||
for(int k = -10; k < 10; k++)
|
||||
{
|
||||
printf("Orig: %02x, Trans: %02x\n",
|
||||
(unsigned char) rnddata2[badoffset+k],
|
||||
(unsigned char) rbuf[j + k]);
|
||||
}
|
||||
|
||||
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
read1 += ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Read Error: " << ret << std::endl;
|
||||
}
|
||||
std::cerr << "Requested " << psize << ", got " << ret << " bytes" << std::endl;
|
||||
std::cerr << "Read " << read1 << " of " << sent2 << " bytes" << std::endl;
|
||||
}
|
||||
|
||||
sleep(2);
|
||||
|
||||
|
||||
while(read2 < sent1)
|
||||
{
|
||||
tcp1.tick();
|
||||
tcp2.tick();
|
||||
|
||||
/* fill with a random little bit more */
|
||||
int psize = (int) ((i + 1.0) * 10000.0 *
|
||||
rand() / (RAND_MAX + 1.0));
|
||||
|
||||
/* limit to what we have! */
|
||||
if (psize > sent1 - read2)
|
||||
{
|
||||
std::cerr << "LAST READ2" << std::endl;
|
||||
psize = sent1 - read2;
|
||||
}
|
||||
|
||||
char rbuf[psize];
|
||||
int rsize = psize;
|
||||
|
||||
int ret = tcp2.read(rbuf, rsize);
|
||||
if (0 < ret)
|
||||
{
|
||||
/* check the data */
|
||||
for(j = 0; j < ret; j++)
|
||||
{
|
||||
if (rnddata1[read2 + j] != rbuf[j])
|
||||
{
|
||||
std::cerr << "Error Data Mismatch @ read2:" << read2;
|
||||
std::cerr << " + j:" << j << " rsize: " << rsize;
|
||||
std::cerr << " Index: " << read2 + j;
|
||||
std::cerr << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
read2 += ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Read Error: " << ret << std::endl;
|
||||
}
|
||||
std::cerr << "Requested " << psize << ", got " << ret << " bytes" << std::endl;
|
||||
std::cerr << "Read " << read2 << " of " << sent1 << " bytes" << std::endl;
|
||||
}
|
||||
|
||||
std::cerr << "Iteration " << i + 1 << " finished correctly!" << std::endl;
|
||||
sleep(5);
|
||||
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int setup_socket(struct sockaddr_in addr)
|
||||
{
|
||||
int sockfd = tou_socket(PF_INET, SOCK_STREAM, 0);
|
||||
|
||||
if (sockfd <= 0)
|
||||
{
|
||||
std::cerr << "Failed to open socket!: ";
|
||||
std::cerr << "Socket Error:" << tou_errno(sockfd) << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::cerr << "Socket Created: " << sockfd << std::endl;
|
||||
|
||||
int err = tou_bind(sockfd, (struct sockaddr *) &addr, sizeof(addr));
|
||||
|
||||
if (err < 0)
|
||||
{
|
||||
std::cerr << "Error: Cannot bind socket: ";
|
||||
std::cerr << err << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::cerr << "Socket1 Bound to: " << addr << std::endl;
|
||||
return sockfd;
|
||||
}
|
||||
|
||||
int connect_socket_pair(int fd1, int fd2,
|
||||
struct sockaddr_in addr1, struct sockaddr_in addr2)
|
||||
{
|
||||
std::cerr << "Socket2 Listening " << std::endl;
|
||||
/* listen */
|
||||
int err = tou_listenfor(fd2, (struct sockaddr *) &addr1, sizeof(addr1));
|
||||
int err_num;
|
||||
|
||||
if (err < 0)
|
||||
{
|
||||
err_num = tou_errno(fd2);
|
||||
if (err_num != EINPROGRESS)
|
||||
{
|
||||
std::cerr << "Cannot Listen!: " << err_num << std::endl;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::cerr << "Socket1 Connecting to: " << addr2 << std::endl;
|
||||
err = tou_connect(fd1, (struct sockaddr *) &addr2, sizeof(addr2));
|
||||
if (err < 0)
|
||||
{
|
||||
err_num = tou_errno(fd1);
|
||||
if (err_num != EINPROGRESS)
|
||||
{
|
||||
std::cerr << "Cannot Connect!: " << err_num << std::endl;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
bool sock1Connected = false;
|
||||
bool sock2Connected = false;
|
||||
|
||||
while((!sock1Connected) || (!sock2Connected))
|
||||
{
|
||||
sleep(1);
|
||||
|
||||
/* sock1 */
|
||||
if((!sock1Connected) && (0 == (err = tou_connected(fd1))))
|
||||
{
|
||||
std::cerr << "Waiting for Connect (Sock1)!" << std::endl;
|
||||
}
|
||||
|
||||
if ((!sock1Connected) && (err < 0))
|
||||
{
|
||||
std::cerr << "Connect Failed" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
else if (!sock1Connected)
|
||||
{
|
||||
// else connected!
|
||||
sock1Connected = true;
|
||||
}
|
||||
|
||||
/* accept - sock2 */
|
||||
struct sockaddr_in inaddr;
|
||||
socklen_t addrlen = sizeof(inaddr);
|
||||
int nsock = -1;
|
||||
|
||||
if ((!sock2Connected) && (0 > (nsock = tou_accept(fd2,
|
||||
(struct sockaddr *) &inaddr, &addrlen))))
|
||||
{
|
||||
errno = tou_errno(fd2);
|
||||
if (errno != EAGAIN)
|
||||
{
|
||||
std::cerr << "Cannot Connect!: " << errno << std::endl;
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Waiting for Connect (Sock2)!" << std::endl;
|
||||
}
|
||||
}
|
||||
else if (nsock > 0)
|
||||
{
|
||||
/* connected */
|
||||
sock2Connected = true;
|
||||
fd2 = nsock;
|
||||
std::cerr << "Socket Accepted from: " << inaddr << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
std::cerr << "Socket Connected" << std::endl;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* This transmits into sockfd1, and check to see that we recv
|
||||
* it back from sockfd2
|
||||
*/
|
||||
|
||||
int send_data_via_pair(int sockfd1, int sockfd2, char *data, int size)
|
||||
{
|
||||
/* what we recvd */
|
||||
char *recvd = (char *) malloc(size * 2);
|
||||
int recvdsize = 0;
|
||||
int sent = 0;
|
||||
int sendsize = 0;
|
||||
|
||||
int ts_start = time(NULL);
|
||||
|
||||
int minsends = 100; /* min of 100 sends to complete all data */
|
||||
/* ensure we don't end up sending nothing */
|
||||
if (minsends * 10 > size)
|
||||
{
|
||||
minsends = size / 10;
|
||||
}
|
||||
|
||||
bool doneWrite = false;
|
||||
bool doneRead = false;
|
||||
while((!doneWrite) || (!doneRead))
|
||||
{
|
||||
/* have a little break */
|
||||
//usleep(10000); /* 0.01 sec */
|
||||
//usleep(250000); /* 0.25 sec */
|
||||
usleep(500000); /* 0.50 sec */
|
||||
/* decide how much to send */
|
||||
sendsize = (int) (((float) (size / minsends)) *
|
||||
(rand() / (RAND_MAX + 1.0)));
|
||||
|
||||
/* limit send */
|
||||
if (sent + sendsize > size)
|
||||
{
|
||||
sendsize = size - sent;
|
||||
}
|
||||
/* if we've finished */
|
||||
if (sent == size)
|
||||
{
|
||||
/* eof */
|
||||
std::cerr << "Write Done!" << std::endl;
|
||||
doneWrite = true;
|
||||
sendsize = 0;
|
||||
}
|
||||
|
||||
/* now we write */
|
||||
if ((sendsize > 0)&&(-1==tou_write(sockfd1,&(data[sent]),sendsize)))
|
||||
{
|
||||
std::cerr << "Write Error: " << tou_errno(sockfd1) << std::endl;
|
||||
if (tou_errno(sockfd1) != EAGAIN)
|
||||
{
|
||||
std::cerr << "FATAL ERROR ending transfer" << std::endl;
|
||||
doneRead = true;
|
||||
doneWrite = true;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
sent += sendsize;
|
||||
}
|
||||
|
||||
int ret = 0;
|
||||
int readsize = (int) (((float) (size / minsends)) *
|
||||
(rand() / (RAND_MAX + 1.0)));
|
||||
|
||||
if (readsize > size - recvdsize)
|
||||
readsize = size - recvdsize;
|
||||
|
||||
if (0 < (ret = tou_read(sockfd2, &(recvd[recvdsize]), readsize)))
|
||||
{
|
||||
std::cerr << "TF(" << ret << ")" << std::endl;
|
||||
recvdsize += ret;
|
||||
}
|
||||
else if (ret == 0)
|
||||
{
|
||||
doneRead = true;
|
||||
std::cerr << "Read Done! (ret:0)" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Read Error: " << tou_errno(sockfd2) << std::endl;
|
||||
std::cerr << "Read " << recvdsize << "/" << size;
|
||||
std::cerr << " attempted: " << readsize << std::endl;
|
||||
if (tou_errno(sockfd2) != EAGAIN)
|
||||
{
|
||||
std::cerr << "FATAL ERROR ending transfer" << std::endl;
|
||||
doneRead = true;
|
||||
doneWrite = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (recvdsize == size)
|
||||
{
|
||||
doneRead = true;
|
||||
std::cerr << "Read Done!" << std::endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* we have transmitted it all, so
|
||||
* check the data
|
||||
*/
|
||||
|
||||
int i;
|
||||
int diffCount = 0;
|
||||
for(i = 0; i < size; i++)
|
||||
{
|
||||
if (recvd[i] != data[i])
|
||||
{
|
||||
diffCount++;
|
||||
if (diffCount < 10)
|
||||
{
|
||||
std::cerr << "Error Byte:" << i << " is different";
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (diffCount)
|
||||
{
|
||||
std::cerr << "Errors (" << diffCount << "/" << size << ") in tranmission ... Exiting!";
|
||||
std::cerr << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int ts_end = time(NULL);
|
||||
double rough_rate = size / (double) (ts_end - ts_start);
|
||||
|
||||
std::cerr << "Successful Data Tranmission: " << size << " in " << ts_end-ts_start << " secs";
|
||||
std::cerr << std::endl;
|
||||
std::cerr << "Approximate Rate: " << rough_rate / 1000.0 << " kbytes/sec";
|
||||
std::cerr << std::endl;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,502 +0,0 @@
|
|||
/*
|
||||
* "$Id: largefile_tou.cc,v 1.2 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".
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
/**********************************************************
|
||||
* This test is designed to test large data blocks/files
|
||||
* running to tou. Currently we see occasional errors
|
||||
* every 1/2 -> 1 MB of transfer....
|
||||
*
|
||||
* This test will continually fill the output buffer,
|
||||
* and then empty the receive one. To ensure the
|
||||
* whole system gets a good workout.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
|
||||
// for printing sockaddr
|
||||
#include "udplayer.h"
|
||||
|
||||
#include "tou.h"
|
||||
#include "tou_net.h"
|
||||
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
int setup_socket(struct sockaddr_in addr);
|
||||
int connect_socket_pair(int fd1, int fd2,
|
||||
struct sockaddr_in addr1, struct sockaddr_in addr2);
|
||||
int send_data_via_pair(int sockfd1, int sockfd2, char *data, int size);
|
||||
|
||||
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 i,j;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
tounet_init();
|
||||
|
||||
|
||||
/* setup the local/remote addresses.
|
||||
*/
|
||||
struct sockaddr_in laddr;
|
||||
struct sockaddr_in raddr;
|
||||
|
||||
laddr.sin_family = AF_INET;
|
||||
raddr.sin_family = AF_INET;
|
||||
|
||||
if ((!tounet_inet_aton(argv[optind], &(laddr.sin_addr))) ||
|
||||
(!tounet_inet_aton(argv[optind+2], &(raddr.sin_addr))))
|
||||
{
|
||||
std::cerr << "Invalid addresses!" << std::endl;
|
||||
usage(argv[0]);
|
||||
}
|
||||
|
||||
unsigned short laddr_port = atoi(argv[optind+1]);
|
||||
unsigned short raddr_port = atoi(argv[optind+3]);
|
||||
|
||||
for(i = 0; i < 10; i++)
|
||||
{
|
||||
laddr.sin_port = htons(laddr_port);
|
||||
raddr.sin_port = htons(raddr_port);
|
||||
//laddr.sin_port = htons(laddr_port + i);
|
||||
//raddr.sin_port = htons(raddr_port + i);
|
||||
|
||||
std::cerr << "Interation: " << i << std::endl;
|
||||
|
||||
|
||||
/* setup the sockets */
|
||||
int sockfd1 = setup_socket(laddr);
|
||||
int sockfd2 = setup_socket(raddr);
|
||||
|
||||
if ((sockfd1 < 0) || (sockfd2 < 0))
|
||||
{
|
||||
std::cerr << "Failed to setup sockets!";
|
||||
std::cerr << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::cerr << "Local Address: " << laddr;
|
||||
std::cerr << " fd: " << sockfd1 << std::endl;
|
||||
std::cerr << "Remote Address: " << raddr;
|
||||
std::cerr << " fd: " << sockfd2 << std::endl;
|
||||
|
||||
/* connect */
|
||||
int err = connect_socket_pair(sockfd1, sockfd2, laddr, raddr);
|
||||
if (err < 0)
|
||||
{
|
||||
std::cerr << "Failed to connect sockets!";
|
||||
std::cerr << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* send the data */
|
||||
int size = 3093237;
|
||||
char rnddata[size];
|
||||
|
||||
int data_loops = (i+1) * (i+1);
|
||||
for(int k = 0; k < data_loops; k++)
|
||||
{
|
||||
std::cerr << "Send Iteration: " << k+1 << " of " << data_loops << std::endl;
|
||||
for(j = 0; j < size; j++)
|
||||
{
|
||||
rnddata[j] = (unsigned char) (255.0 *
|
||||
rand() / (RAND_MAX + 1.0));
|
||||
}
|
||||
send_data_via_pair(sockfd1, sockfd2, rnddata, size);
|
||||
std::cerr << "Send Iteration: " << k+1 << " of " << data_loops << std::endl;
|
||||
sleep(2);
|
||||
}
|
||||
|
||||
std::cerr << "Completed Successful transfer of " << size * data_loops << " bytes";
|
||||
std::cerr << std::endl;
|
||||
|
||||
sleep(10);
|
||||
std::cerr << "closing sockfd1: " << sockfd1 << std::endl;
|
||||
tou_close(sockfd1);
|
||||
|
||||
std::cerr << "closing sockfd2: " << sockfd2 << std::endl;
|
||||
tou_close(sockfd2);
|
||||
|
||||
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int setup_socket(struct sockaddr_in addr)
|
||||
{
|
||||
int sockfd = tou_socket(PF_INET, SOCK_STREAM, 0);
|
||||
|
||||
if (sockfd <= 0)
|
||||
{
|
||||
std::cerr << "Failed to open socket!: ";
|
||||
std::cerr << "Socket Error:" << tou_errno(sockfd) << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::cerr << "Socket Created: " << sockfd << std::endl;
|
||||
|
||||
int err = tou_bind(sockfd, (struct sockaddr *) &addr, sizeof(addr));
|
||||
|
||||
if (err < 0)
|
||||
{
|
||||
std::cerr << "Error: Cannot bind socket: ";
|
||||
std::cerr << err << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::cerr << "Socket1 Bound to: " << addr << std::endl;
|
||||
return sockfd;
|
||||
}
|
||||
|
||||
int connect_socket_pair(int fd1, int fd2,
|
||||
struct sockaddr_in addr1, struct sockaddr_in addr2)
|
||||
{
|
||||
std::cerr << "Socket2 Listening " << std::endl;
|
||||
/* listen */
|
||||
int err = tou_listenfor(fd2, (struct sockaddr *) &addr1, sizeof(addr1));
|
||||
int err_num;
|
||||
|
||||
if (err < 0)
|
||||
{
|
||||
err_num = tou_errno(fd2);
|
||||
if (err_num != EINPROGRESS)
|
||||
{
|
||||
std::cerr << "Cannot Listen!: " << err_num << std::endl;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::cerr << "Socket1 Connecting to: " << addr2 << std::endl;
|
||||
err = tou_connect(fd1, (struct sockaddr *) &addr2, sizeof(addr2), 30);
|
||||
if (err < 0)
|
||||
{
|
||||
err_num = tou_errno(fd1);
|
||||
if (err_num != EINPROGRESS)
|
||||
{
|
||||
std::cerr << "Cannot Connect!: " << err_num << std::endl;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
bool sock1Connected = false;
|
||||
bool sock2Connected = false;
|
||||
|
||||
while((!sock1Connected) || (!sock2Connected))
|
||||
{
|
||||
sleep(1);
|
||||
|
||||
/* sock1 */
|
||||
if((!sock1Connected) && (0 == (err = tou_connected(fd1))))
|
||||
{
|
||||
std::cerr << "Waiting for Connect (Sock1)!" << std::endl;
|
||||
}
|
||||
|
||||
if ((!sock1Connected) && (err < 0))
|
||||
{
|
||||
std::cerr << "Connect Failed" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
else if (!sock1Connected)
|
||||
{
|
||||
// else connected!
|
||||
sock1Connected = true;
|
||||
}
|
||||
|
||||
/* accept - sock2 */
|
||||
struct sockaddr_in inaddr;
|
||||
socklen_t addrlen = sizeof(inaddr);
|
||||
int nsock = -1;
|
||||
|
||||
if ((!sock2Connected) && (0 > (nsock = tou_accept(fd2,
|
||||
(struct sockaddr *) &inaddr, &addrlen))))
|
||||
{
|
||||
errno = tou_errno(fd2);
|
||||
if (errno != EAGAIN)
|
||||
{
|
||||
std::cerr << "Cannot Connect!: " << errno << std::endl;
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Waiting for Connect (Sock2)!" << std::endl;
|
||||
}
|
||||
}
|
||||
else if (nsock > 0)
|
||||
{
|
||||
/* connected */
|
||||
sock2Connected = true;
|
||||
fd2 = nsock;
|
||||
std::cerr << "Socket Accepted from: " << inaddr << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
std::cerr << "Socket Connected" << std::endl;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* This transmits into sockfd1, and check to see that we recv
|
||||
* it back from sockfd2
|
||||
*/
|
||||
|
||||
int send_data_via_pair(int sockfd1, int sockfd2, char *data, int size)
|
||||
{
|
||||
/* what we recvd */
|
||||
char *recvd = (char *) malloc(size * 2);
|
||||
int recvdsize = 0;
|
||||
int sent = 0;
|
||||
int sendsize = 0;
|
||||
|
||||
int ts_start = time(NULL);
|
||||
|
||||
int minsends = 100; /* min of 100 sends to complete all data */
|
||||
/* ensure we don't end up sending nothing */
|
||||
if (minsends * 10 > size)
|
||||
{
|
||||
minsends = size / 10;
|
||||
}
|
||||
|
||||
bool doneWrite = false;
|
||||
bool doneRead = false;
|
||||
|
||||
int maxtransfer = (int) (size / minsends) + (int) (((float) (size / minsends)) *
|
||||
(rand() / (RAND_MAX + 1.0)));
|
||||
/* allow the transfer ratio read/write to vary between 0.4->1,5. */
|
||||
double tf_ratio = 0.4 + 1.1 * (rand() / (RAND_MAX + 1.0));
|
||||
|
||||
while((!doneWrite) || (!doneRead))
|
||||
{
|
||||
/* have a little break */
|
||||
//usleep(10000); /* 0.01 sec */
|
||||
usleep(20000); /* 0.02 sec */
|
||||
//usleep(250000); /* 0.25 sec */
|
||||
//usleep(500000); /* 0.50 sec */
|
||||
/* decide how much to send */
|
||||
sendsize = (int) (((float) (maxtransfer)) *
|
||||
(rand() / (RAND_MAX + 1.0)));
|
||||
|
||||
/* limit send */
|
||||
if (sent + sendsize > size)
|
||||
{
|
||||
std::cerr << "Last WRITE!" << std::endl;
|
||||
sendsize = size - sent;
|
||||
}
|
||||
/* if we've finished */
|
||||
if (sent == size)
|
||||
{
|
||||
/* eof */
|
||||
std::cerr << "Write Done!" << std::endl;
|
||||
doneWrite = true;
|
||||
sendsize = 0;
|
||||
}
|
||||
|
||||
/* now we write */
|
||||
if ((sendsize > 0)&&(-1==tou_write(sockfd1,&(data[sent]),sendsize)))
|
||||
{
|
||||
std::cerr << "Write Error: " << tou_errno(sockfd1) << std::endl;
|
||||
if (tou_errno(sockfd1) != EAGAIN)
|
||||
{
|
||||
std::cerr << "FATAL ERROR ending transfer" << std::endl;
|
||||
doneRead = true;
|
||||
doneWrite = true;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
sent += sendsize;
|
||||
}
|
||||
|
||||
int ret = 0;
|
||||
|
||||
// read size about 1/4 of write to exercise the buffers.
|
||||
int readsize = (int) (((float) (maxtransfer)) * tf_ratio *
|
||||
(rand() / (RAND_MAX + 1.0)));
|
||||
|
||||
if (readsize > size - recvdsize)
|
||||
{
|
||||
std::cerr << "Last READ!" << std::endl;
|
||||
readsize = size - recvdsize;
|
||||
}
|
||||
|
||||
if (0 < (ret = tou_read(sockfd2, &(recvd[recvdsize]), readsize)))
|
||||
{
|
||||
std::cerr << "TF(" << ret << ")" << std::endl;
|
||||
|
||||
/* check the data at this point */
|
||||
|
||||
int i;
|
||||
int diffCount = 0;
|
||||
int init_err = 0;
|
||||
for(i = 0; i < ret; i++)
|
||||
{
|
||||
if (recvd[recvdsize + i] != data[recvdsize + i])
|
||||
{
|
||||
if (!diffCount)
|
||||
{
|
||||
init_err = i;
|
||||
}
|
||||
diffCount++;
|
||||
if (diffCount < 10)
|
||||
{
|
||||
std::cerr << "Error Byte:" << recvdsize + i << " is different";
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (diffCount)
|
||||
{
|
||||
std::cerr << "Errors (" << diffCount << "/" << ret << ") in read, ";
|
||||
std::cerr << std::endl;
|
||||
std::cerr << " At Blk Start: " << recvdsize << " offset: " << init_err;
|
||||
std::cerr << " ==> At index: " << recvdsize + init_err << "... Exiting!";
|
||||
std::cerr << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Checked (" << recvdsize << "+ 0 => " << ret << ") Okay" << std::endl;
|
||||
}
|
||||
|
||||
recvdsize += ret;
|
||||
}
|
||||
else if (ret == 0)
|
||||
{
|
||||
//doneRead = true;
|
||||
std::cerr << "Read Done? (ret:0)" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Read Error: " << tou_errno(sockfd2) << std::endl;
|
||||
std::cerr << "Read " << recvdsize << "/" << size;
|
||||
std::cerr << " attempted: " << readsize << std::endl;
|
||||
if (tou_errno(sockfd2) != EAGAIN)
|
||||
{
|
||||
std::cerr << "FATAL ERROR ending transfer" << std::endl;
|
||||
doneRead = true;
|
||||
doneWrite = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (recvdsize == size)
|
||||
{
|
||||
doneRead = true;
|
||||
std::cerr << "Read Done!" << std::endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* we have transmitted it all, so
|
||||
* check the data
|
||||
*/
|
||||
|
||||
int i;
|
||||
int diffCount = 0;
|
||||
for(i = 0; i < size; i++)
|
||||
{
|
||||
if (recvd[i] != data[i])
|
||||
{
|
||||
diffCount++;
|
||||
if (diffCount < 10)
|
||||
{
|
||||
std::cerr << "Error Byte:" << i << " is different";
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (diffCount)
|
||||
{
|
||||
std::cerr << "Errors (" << diffCount << "/" << size << ") in tranmission ... Exiting!";
|
||||
std::cerr << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int ts_end = time(NULL);
|
||||
double rough_rate = size / (double) (ts_end - ts_start);
|
||||
|
||||
std::cerr << "Successful Data Tranmission: " << size << " in " << ts_end-ts_start << " secs";
|
||||
std::cerr << std::endl;
|
||||
std::cerr << "Approximate Rate: " << rough_rate / 1000.0 << " kbytes/sec";
|
||||
std::cerr << std::endl;
|
||||
std::cerr << "Transfer Ratio: " << tf_ratio;
|
||||
std::cerr << std::endl;
|
||||
|
||||
free(recvd);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,491 +0,0 @@
|
|||
/*
|
||||
* "$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>
|
||||
|
||||
//#define USE_TCP_SOCKET
|
||||
|
||||
// for printing sockaddr
|
||||
#include "udplayer.h"
|
||||
|
||||
#ifndef USE_TCP_SOCKET
|
||||
#include "tou.h"
|
||||
#endif
|
||||
|
||||
#include "tou_net.h"
|
||||
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
|
||||
/* This is a simple test to ensure that the tou behaviour
|
||||
* is almost identical to a standard tcp socket.
|
||||
*
|
||||
* In this version we open 2 sockets, and attempt to
|
||||
* communicate with ourselves....
|
||||
*
|
||||
*/
|
||||
|
||||
int Check_Socket(int fd);
|
||||
|
||||
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 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;
|
||||
}
|
||||
|
||||
tounet_init();
|
||||
|
||||
/* setup the local/remote addresses.
|
||||
*/
|
||||
struct sockaddr_in laddr;
|
||||
struct sockaddr_in raddr;
|
||||
|
||||
laddr.sin_family = AF_INET;
|
||||
raddr.sin_family = AF_INET;
|
||||
|
||||
if ((!tounet_inet_aton(argv[optind], &(laddr.sin_addr))) ||
|
||||
(!tounet_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;
|
||||
|
||||
|
||||
#ifdef USE_TCP_SOCKET
|
||||
int sockfd = socket(PF_INET, SOCK_STREAM, 0);
|
||||
int sockfd2 = socket(PF_INET, SOCK_STREAM, 0);
|
||||
#else
|
||||
int sockfd = tou_socket(PF_INET, SOCK_STREAM, 0);
|
||||
int sockfd2 = tou_socket(PF_INET, SOCK_STREAM, 0);
|
||||
#endif
|
||||
if ((sockfd <= 0) || (sockfd2 <= 0))
|
||||
{
|
||||
std::cerr << "Failed to open socket!: ";
|
||||
#ifdef USE_TCP_SOCKET
|
||||
std::cerr << "Socket Error:" << errno << std::endl;
|
||||
#else
|
||||
std::cerr << "Socket Error:" << tou_errno(sockfd) << std::endl;
|
||||
std::cerr << "Socket Error:" << tou_errno(sockfd2) << std::endl;
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
std::cerr << "Sockets Created: " << sockfd << " & " << sockfd2 << std::endl;
|
||||
|
||||
|
||||
/* make nonblocking */
|
||||
#ifdef USE_TCP_SOCKET
|
||||
int err = fcntl(sockfd,F_SETFD,O_NONBLOCK);
|
||||
int err2 = fcntl(sockfd2,F_SETFD,O_NONBLOCK);
|
||||
#else
|
||||
int err = 0;
|
||||
int err2 = 0;
|
||||
#endif
|
||||
if ((err < 0) || (err2 < 0))
|
||||
{
|
||||
std::cerr << "Error: Cannot make socket NON-Blocking: ";
|
||||
std::cerr << err << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::cerr << "Socket Non-Blocking" << std::endl;
|
||||
|
||||
#ifdef USE_TCP_SOCKET
|
||||
err = bind(sockfd, (struct sockaddr *) &laddr, sizeof(laddr));
|
||||
err2 = bind(sockfd2, (struct sockaddr *) &raddr, sizeof(raddr));
|
||||
#else
|
||||
err = tou_bind(sockfd, (struct sockaddr *) &laddr, sizeof(laddr));
|
||||
err2 = tou_bind(sockfd2, (struct sockaddr *) &raddr, sizeof(raddr));
|
||||
#endif
|
||||
if ((err < 0) || (err2 < 0))
|
||||
{
|
||||
std::cerr << "Error: Cannot bind socket: ";
|
||||
std::cerr << err << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::cerr << "Socket1 Bound to: " << laddr << std::endl;
|
||||
std::cerr << "Socket2 Bound to: " << raddr << std::endl;
|
||||
|
||||
// listening.
|
||||
if (1) // socket2.
|
||||
{
|
||||
std::cerr << "Socket2 Listening " << std::endl;
|
||||
/* listen */
|
||||
#ifdef USE_TCP_SOCKET
|
||||
err = listen(sockfd2, 1);
|
||||
#else
|
||||
err = tou_listenfor(sockfd2,
|
||||
(struct sockaddr *) &laddr, sizeof(laddr));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
if (1) // only one program.
|
||||
{
|
||||
std::cerr << "Socket1 Connecting to: " << raddr << std::endl;
|
||||
#ifdef USE_TCP_SOCKET
|
||||
err = connect(sockfd, (struct sockaddr *) &raddr, sizeof(raddr));
|
||||
#else
|
||||
err = tou_connect(sockfd, (struct sockaddr *) &raddr, sizeof(raddr), 30);
|
||||
#endif
|
||||
if (err < 0)
|
||||
{
|
||||
#ifndef USE_TCP_SOCKET
|
||||
errno = tou_errno(sockfd);
|
||||
#endif
|
||||
if (errno != EINPROGRESS)
|
||||
{
|
||||
std::cerr << "Cannot Connect!: " << errno << std::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool sock1Connected = false;
|
||||
bool sock2Connected = false;
|
||||
|
||||
while((!sock1Connected) || (!sock2Connected))
|
||||
{
|
||||
sleep(1);
|
||||
|
||||
|
||||
/* sock1 */
|
||||
#ifdef USE_TCP_SOCKET
|
||||
if((!sock1Connected) && (0 == (err = Check_Socket(sockfd))))
|
||||
#else
|
||||
if((!sock1Connected) && (0 == (err = tou_connected(sockfd))))
|
||||
#endif
|
||||
{
|
||||
std::cerr << "Waiting for Connect (Sock1)!" << std::endl;
|
||||
}
|
||||
if ((!sock1Connected) && (err < 0))
|
||||
{
|
||||
std::cerr << "Connect Failed" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
else if (!sock1Connected)
|
||||
{
|
||||
// else connected!
|
||||
sock1Connected = true;
|
||||
}
|
||||
|
||||
/* accept - sock2 */
|
||||
struct sockaddr_in inaddr;
|
||||
socklen_t addrlen = sizeof(inaddr);
|
||||
int nsock = -1;
|
||||
|
||||
#ifdef USE_TCP_SOCKET
|
||||
if ((!sock2Connected) && (0 > (nsock = accept(sockfd2,
|
||||
(struct sockaddr *) &inaddr, &addrlen))))
|
||||
#else
|
||||
if ((!sock2Connected) && (0 > (nsock = tou_accept(sockfd2,
|
||||
(struct sockaddr *) &inaddr, &addrlen))))
|
||||
#endif
|
||||
{
|
||||
#ifndef USE_TCP_SOCKET
|
||||
errno = tou_errno(sockfd2);
|
||||
#endif
|
||||
if (errno != EAGAIN)
|
||||
{
|
||||
std::cerr << "Cannot Connect!: " << errno << std::endl;
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Waiting for Connect (Sock2)!" << std::endl;
|
||||
}
|
||||
}
|
||||
else if (nsock > 0)
|
||||
{
|
||||
/* connected */
|
||||
sock2Connected = true;
|
||||
sockfd2 = nsock;
|
||||
std::cerr << "Socket Accepted from: " << inaddr << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
std::cerr << "Socket Connected" << std::endl;
|
||||
|
||||
/* send data */
|
||||
int bufsize = 1511;
|
||||
char buffer[bufsize];
|
||||
char data[bufsize];
|
||||
int readsize = 0;
|
||||
|
||||
tounet_fcntl(0, F_SETFL, O_NONBLOCK);
|
||||
tounet_fcntl(1,F_SETFL,O_NONBLOCK);
|
||||
|
||||
bool doneWrite = false;
|
||||
bool doneRead = false;
|
||||
bool blockread = false;
|
||||
while((!doneWrite) || (!doneRead))
|
||||
{
|
||||
/* read -> write_socket... */
|
||||
sleep(1);
|
||||
if (blockread != true)
|
||||
{
|
||||
readsize = read(0, buffer, bufsize);
|
||||
}
|
||||
if (readsize == 0)
|
||||
{
|
||||
/* eof */
|
||||
doneWrite = true;
|
||||
}
|
||||
/* now we write */
|
||||
#ifdef USE_TCP_SOCKET
|
||||
if ((readsize > 0) && (-1 == write(sockfd, buffer, readsize)))
|
||||
#else
|
||||
if ((readsize > 0) && (-1 == tou_write(sockfd, buffer, readsize)))
|
||||
#endif
|
||||
{
|
||||
//std::cerr << "Blocked Write!" << std::endl;
|
||||
#ifndef USE_TCP_SOCKET
|
||||
//std::cerr << "Error: " << tou_errno(sockfd) << std::endl;
|
||||
#endif
|
||||
blockread = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
blockread = false;
|
||||
totalwbytes += readsize;
|
||||
}
|
||||
|
||||
int ret = 0;
|
||||
#ifdef USE_TCP_SOCKET
|
||||
if (0 < (ret = read(sockfd2, data, bufsize)))
|
||||
#else
|
||||
if (0 < (ret = tou_read(sockfd2, data, bufsize)))
|
||||
#endif
|
||||
|
||||
{
|
||||
std::cerr << "TF(" << ret << ")" << std::endl;
|
||||
write(1, data, ret);
|
||||
totalrbytes += ret;
|
||||
}
|
||||
else if (ret == 0)
|
||||
{
|
||||
doneRead = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
//std::cerr << "Blocked Read!" << std::endl;
|
||||
#ifndef USE_TCP_SOCKET
|
||||
//std::cerr << "Error: " << tou_errno(sockfd) << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
#ifdef USE_TCP_SOCKET
|
||||
close(sockfd);
|
||||
close(sockfd2);
|
||||
#else
|
||||
/* this is blocking??? */
|
||||
tou_close(sockfd);
|
||||
tou_close(sockfd2);
|
||||
#endif
|
||||
|
||||
std::cerr << "Transfer Complete: " << totalwbytes << " bytes";
|
||||
std::cerr << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef USE_TCP_SOCKET
|
||||
|
||||
|
||||
int Check_Socket(int fd)
|
||||
{
|
||||
std::cerr << "Check_Socket()" << std::endl;
|
||||
|
||||
std::cerr << "1) Checking with Select()" << std::endl;
|
||||
|
||||
fd_set ReadFDs, WriteFDs, ExceptFDs;
|
||||
FD_ZERO(&ReadFDs);
|
||||
FD_ZERO(&WriteFDs);
|
||||
FD_ZERO(&ExceptFDs);
|
||||
|
||||
FD_SET(fd, &ReadFDs);
|
||||
FD_SET(fd, &WriteFDs);
|
||||
FD_SET(fd, &ExceptFDs);
|
||||
|
||||
struct timeval timeout;
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_usec = 0;
|
||||
|
||||
int sr = 0;
|
||||
if (0 > (sr = select(fd + 1,
|
||||
&ReadFDs, &WriteFDs, &ExceptFDs, &timeout)))
|
||||
{
|
||||
std::cerr << "Check_Socket() Select ERROR: " << sr << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (FD_ISSET(fd, &ExceptFDs))
|
||||
{
|
||||
std::cerr << "Check_Socket() Exception on socket!" << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (FD_ISSET(fd, &WriteFDs))
|
||||
{
|
||||
std::cerr << "Check_Socket() Can Write!" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
// not ready return 0;
|
||||
std::cerr << "Check_Socket() Cannot Write!" << std::endl;
|
||||
std::cerr << "Check_Socket() Socket Not Ready!" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (FD_ISSET(fd, &ReadFDs))
|
||||
{
|
||||
std::cerr << "Check_Socket() Can Read!" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Check_Socket() Cannot Read!" << std::endl;
|
||||
std::cerr << "Check_Socket() Socket Not Ready!" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::cerr << "Select() Tests indicate Socket Good!" << std::endl;
|
||||
std::cerr << "2) Checking with getsockopt()" << std::endl;
|
||||
|
||||
int err = 1;
|
||||
socklen_t optlen = 4;
|
||||
if (0==getsockopt(fd, SOL_SOCKET, SO_ERROR, &err, &optlen))
|
||||
{
|
||||
std::cerr << "Check_Socket() getsockopt returned :" << err;
|
||||
std::cerr << ", optlen:" << optlen;
|
||||
std::cerr << std::endl;
|
||||
|
||||
if (err == 0)
|
||||
{
|
||||
std::cerr << "Check_Socket() getsockopt";
|
||||
std::cerr << " Indicates TCP Connection Complete:";
|
||||
std::cerr << std::endl;
|
||||
return 1;
|
||||
}
|
||||
else if (err == EINPROGRESS)
|
||||
{
|
||||
std::cerr << "Check_Socket() getsockopt";
|
||||
std::cerr << " Indicates TCP Connection INPROGRESS";
|
||||
std::cerr << std::endl;
|
||||
return 0;
|
||||
}
|
||||
else if ((err == ENETUNREACH) || (err == ETIMEDOUT))
|
||||
{
|
||||
std::cerr << "Check_Socket() getsockopt";
|
||||
std::cerr << " Indicates TCP Connection ENETUNREACH/ETIMEDOUT";
|
||||
std::cerr << std::endl;
|
||||
return -1;
|
||||
}
|
||||
else if ((err == EHOSTUNREACH) || (err == EHOSTDOWN))
|
||||
{
|
||||
std::cerr << "Check_Socket() getsockopt";
|
||||
std::cerr << " Indicates TCP Connection ENETUNREACH/ETIMEDOUT";
|
||||
std::cerr << std::endl;
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Check_Socket() getsockopt";
|
||||
std::cerr << " Indicates Other Error: " << err;
|
||||
std::cerr << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Check_Socket() getsockopt";
|
||||
std::cerr << " FAILED ";
|
||||
std::cerr << std::endl;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
|
||||
int Check_Socket(int fd)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,453 +0,0 @@
|
|||
/*
|
||||
* "$Id: reset_tou.cc,v 1.4 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".
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
/**********************************************************
|
||||
* This test is designed to ensure that tou networking
|
||||
* can be reset, and restarted.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
|
||||
// for printing sockaddr
|
||||
#include "udplayer.h"
|
||||
|
||||
#include "tou.h"
|
||||
#include "tou_net.h"
|
||||
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
|
||||
/* This is a simple test to ensure that the tou behaviour
|
||||
* is almost identical to a standard tcp socket.
|
||||
*
|
||||
* In this version we open 2 sockets, and attempt to
|
||||
* communicate with ourselves....
|
||||
*
|
||||
*/
|
||||
|
||||
int setup_socket(struct sockaddr_in addr);
|
||||
int connect_socket_pair(int fd1, int fd2,
|
||||
struct sockaddr_in addr1, struct sockaddr_in addr2);
|
||||
int send_data_via_pair(int sockfd1, int sockfd2, char *data, int size);
|
||||
|
||||
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 i,j;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
tounet_init();
|
||||
|
||||
|
||||
/* setup the local/remote addresses.
|
||||
*/
|
||||
struct sockaddr_in laddr;
|
||||
struct sockaddr_in raddr;
|
||||
|
||||
laddr.sin_family = AF_INET;
|
||||
raddr.sin_family = AF_INET;
|
||||
|
||||
if ((!tounet_inet_aton(argv[optind], &(laddr.sin_addr))) ||
|
||||
(!tounet_inet_aton(argv[optind+2], &(raddr.sin_addr))))
|
||||
{
|
||||
std::cerr << "Invalid addresses!" << std::endl;
|
||||
usage(argv[0]);
|
||||
}
|
||||
|
||||
unsigned short laddr_port = atoi(argv[optind+1]);
|
||||
unsigned short raddr_port = atoi(argv[optind+3]);
|
||||
|
||||
for(i = 0; i < 10; i++)
|
||||
{
|
||||
laddr.sin_port = htons(laddr_port);
|
||||
raddr.sin_port = htons(raddr_port);
|
||||
//laddr.sin_port = htons(laddr_port + i);
|
||||
//raddr.sin_port = htons(raddr_port + i);
|
||||
|
||||
std::cerr << "Interation: " << i << std::endl;
|
||||
|
||||
|
||||
/* setup the sockets */
|
||||
int sockfd1 = setup_socket(laddr);
|
||||
int sockfd2 = setup_socket(raddr);
|
||||
|
||||
if ((sockfd1 < 0) || (sockfd2 < 0))
|
||||
{
|
||||
std::cerr << "Failed to setup sockets!";
|
||||
std::cerr << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::cerr << "Local Address: " << laddr;
|
||||
std::cerr << " fd: " << sockfd1 << std::endl;
|
||||
std::cerr << "Remote Address: " << raddr;
|
||||
std::cerr << " fd: " << sockfd2 << std::endl;
|
||||
|
||||
/* connect */
|
||||
int err = connect_socket_pair(sockfd1, sockfd2, laddr, raddr);
|
||||
if (err < 0)
|
||||
{
|
||||
std::cerr << "Failed to connect sockets!";
|
||||
std::cerr << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* send the data */
|
||||
int size = 102400;
|
||||
char rnddata[size];
|
||||
|
||||
int data_loops = (i+1) * (i+1);
|
||||
for(int k = 0; k < data_loops; k++)
|
||||
{
|
||||
std::cerr << "Send Iteration: " << k+1 << " of " << data_loops << std::endl;
|
||||
for(j = 0; j < size; j++)
|
||||
{
|
||||
rnddata[j] = (unsigned char) (255.0 *
|
||||
rand() / (RAND_MAX + 1.0));
|
||||
}
|
||||
send_data_via_pair(sockfd1, sockfd2, rnddata, size);
|
||||
std::cerr << "Send Iteration: " << k+1 << " of " << data_loops << std::endl;
|
||||
sleep(2);
|
||||
}
|
||||
|
||||
std::cerr << "Completed Successful transfer of " << size * data_loops << " bytes";
|
||||
std::cerr << std::endl;
|
||||
|
||||
sleep(10);
|
||||
std::cerr << "closing sockfd1: " << sockfd1 << std::endl;
|
||||
tou_close(sockfd1);
|
||||
|
||||
std::cerr << "closing sockfd2: " << sockfd2 << std::endl;
|
||||
tou_close(sockfd2);
|
||||
|
||||
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int setup_socket(struct sockaddr_in addr)
|
||||
{
|
||||
int sockfd = tou_socket(PF_INET, SOCK_STREAM, 0);
|
||||
|
||||
if (sockfd <= 0)
|
||||
{
|
||||
std::cerr << "Failed to open socket!: ";
|
||||
std::cerr << "Socket Error:" << tou_errno(sockfd) << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::cerr << "Socket Created: " << sockfd << std::endl;
|
||||
|
||||
int err = tou_bind(sockfd, (struct sockaddr *) &addr, sizeof(addr));
|
||||
|
||||
if (err < 0)
|
||||
{
|
||||
std::cerr << "Error: Cannot bind socket: ";
|
||||
std::cerr << err << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::cerr << "Socket1 Bound to: " << addr << std::endl;
|
||||
return sockfd;
|
||||
}
|
||||
|
||||
int connect_socket_pair(int fd1, int fd2,
|
||||
struct sockaddr_in addr1, struct sockaddr_in addr2)
|
||||
{
|
||||
std::cerr << "Socket2 Listening " << std::endl;
|
||||
/* listen */
|
||||
int err = tou_listenfor(fd2, (struct sockaddr *) &addr1, sizeof(addr1));
|
||||
int err_num;
|
||||
|
||||
if (err < 0)
|
||||
{
|
||||
err_num = tou_errno(fd2);
|
||||
if (err_num != EINPROGRESS)
|
||||
{
|
||||
std::cerr << "Cannot Listen!: " << err_num << std::endl;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::cerr << "Socket1 Connecting to: " << addr2 << std::endl;
|
||||
err = tou_connect(fd1, (struct sockaddr *) &addr2, sizeof(addr2), 30);
|
||||
if (err < 0)
|
||||
{
|
||||
err_num = tou_errno(fd1);
|
||||
if (err_num != EINPROGRESS)
|
||||
{
|
||||
std::cerr << "Cannot Connect!: " << err_num << std::endl;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
bool sock1Connected = false;
|
||||
bool sock2Connected = false;
|
||||
|
||||
while((!sock1Connected) || (!sock2Connected))
|
||||
{
|
||||
sleep(1);
|
||||
|
||||
/* sock1 */
|
||||
if((!sock1Connected) && (0 == (err = tou_connected(fd1))))
|
||||
{
|
||||
std::cerr << "Waiting for Connect (Sock1)!" << std::endl;
|
||||
}
|
||||
|
||||
if ((!sock1Connected) && (err < 0))
|
||||
{
|
||||
std::cerr << "Connect Failed" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
else if (!sock1Connected)
|
||||
{
|
||||
// else connected!
|
||||
sock1Connected = true;
|
||||
}
|
||||
|
||||
/* accept - sock2 */
|
||||
struct sockaddr_in inaddr;
|
||||
socklen_t addrlen = sizeof(inaddr);
|
||||
int nsock = -1;
|
||||
|
||||
if ((!sock2Connected) && (0 > (nsock = tou_accept(fd2,
|
||||
(struct sockaddr *) &inaddr, &addrlen))))
|
||||
{
|
||||
errno = tou_errno(fd2);
|
||||
if (errno != EAGAIN)
|
||||
{
|
||||
std::cerr << "Cannot Connect!: " << errno << std::endl;
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Waiting for Connect (Sock2)!" << std::endl;
|
||||
}
|
||||
}
|
||||
else if (nsock > 0)
|
||||
{
|
||||
/* connected */
|
||||
sock2Connected = true;
|
||||
fd2 = nsock;
|
||||
std::cerr << "Socket Accepted from: " << inaddr << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
std::cerr << "Socket Connected" << std::endl;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* This transmits into sockfd1, and check to see that we recv
|
||||
* it back from sockfd2
|
||||
*/
|
||||
|
||||
int send_data_via_pair(int sockfd1, int sockfd2, char *data, int size)
|
||||
{
|
||||
/* what we recvd */
|
||||
char *recvd = (char *) malloc(size * 2);
|
||||
int recvdsize = 0;
|
||||
int sent = 0;
|
||||
int sendsize = 0;
|
||||
|
||||
int ts_start = time(NULL);
|
||||
|
||||
int minsends = 100; /* min of 100 sends to complete all data */
|
||||
/* ensure we don't end up sending nothing */
|
||||
if (minsends * 10 > size)
|
||||
{
|
||||
minsends = size / 10;
|
||||
}
|
||||
|
||||
bool doneWrite = false;
|
||||
bool doneRead = false;
|
||||
while((!doneWrite) || (!doneRead))
|
||||
{
|
||||
/* have a little break */
|
||||
//usleep(10000); /* 0.01 sec */
|
||||
//usleep(250000); /* 0.25 sec */
|
||||
usleep(500000); /* 0.50 sec */
|
||||
/* decide how much to send */
|
||||
sendsize = (int) (((float) (size / minsends)) *
|
||||
(rand() / (RAND_MAX + 1.0)));
|
||||
|
||||
/* limit send */
|
||||
if (sent + sendsize > size)
|
||||
{
|
||||
sendsize = size - sent;
|
||||
}
|
||||
/* if we've finished */
|
||||
if (sent == size)
|
||||
{
|
||||
/* eof */
|
||||
std::cerr << "Write Done!" << std::endl;
|
||||
doneWrite = true;
|
||||
sendsize = 0;
|
||||
}
|
||||
|
||||
/* now we write */
|
||||
if ((sendsize > 0)&&(-1==tou_write(sockfd1,&(data[sent]),sendsize)))
|
||||
{
|
||||
std::cerr << "Write Error: " << tou_errno(sockfd1) << std::endl;
|
||||
if (tou_errno(sockfd1) != EAGAIN)
|
||||
{
|
||||
std::cerr << "FATAL ERROR ending transfer" << std::endl;
|
||||
doneRead = true;
|
||||
doneWrite = true;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
sent += sendsize;
|
||||
}
|
||||
|
||||
int ret = 0;
|
||||
int readsize = (int) (((float) (size / minsends)) *
|
||||
(rand() / (RAND_MAX + 1.0)));
|
||||
|
||||
if (readsize > size - recvdsize)
|
||||
readsize = size - recvdsize;
|
||||
|
||||
if (0 < (ret = tou_read(sockfd2, &(recvd[recvdsize]), readsize)))
|
||||
{
|
||||
std::cerr << "TF(" << ret << ")" << std::endl;
|
||||
recvdsize += ret;
|
||||
}
|
||||
else if (ret == 0)
|
||||
{
|
||||
doneRead = true;
|
||||
std::cerr << "Read Done! (ret:0)" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Read Error: " << tou_errno(sockfd2) << std::endl;
|
||||
std::cerr << "Read " << recvdsize << "/" << size;
|
||||
std::cerr << " attempted: " << readsize << std::endl;
|
||||
if (tou_errno(sockfd2) != EAGAIN)
|
||||
{
|
||||
std::cerr << "FATAL ERROR ending transfer" << std::endl;
|
||||
doneRead = true;
|
||||
doneWrite = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (recvdsize == size)
|
||||
{
|
||||
doneRead = true;
|
||||
std::cerr << "Read Done!" << std::endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* we have transmitted it all, so
|
||||
* check the data
|
||||
*/
|
||||
|
||||
int i;
|
||||
int diffCount = 0;
|
||||
for(i = 0; i < size; i++)
|
||||
{
|
||||
if (recvd[i] != data[i])
|
||||
{
|
||||
diffCount++;
|
||||
if (diffCount < 10)
|
||||
{
|
||||
std::cerr << "Error Byte:" << i << " is different";
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (diffCount)
|
||||
{
|
||||
std::cerr << "Errors (" << diffCount << "/" << size << ") in tranmission ... Exiting!";
|
||||
std::cerr << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int ts_end = time(NULL);
|
||||
double rough_rate = size / (double) (ts_end - ts_start);
|
||||
|
||||
std::cerr << "Successful Data Tranmission: " << size << " in " << ts_end-ts_start << " secs";
|
||||
std::cerr << std::endl;
|
||||
std::cerr << "Approximate Rate: " << rough_rate / 1000.0 << " kbytes/sec";
|
||||
std::cerr << std::endl;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
70
libretroshare/src/tcponudp/rsudpstack.h
Normal file
70
libretroshare/src/tcponudp/rsudpstack.h
Normal file
|
@ -0,0 +1,70 @@
|
|||
#ifndef RS_UDP_STACK_RECEIVER_H
|
||||
#define RS_UDP_STACK_RECEIVER_H
|
||||
|
||||
/*
|
||||
* tcponudp/rsudpstack.h
|
||||
*
|
||||
* libretroshare.
|
||||
*
|
||||
* Copyright 2010 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 3 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".
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/*******************************************************/
|
||||
#ifdef RS_USE_BITDHT
|
||||
|
||||
#include "udp/udpstack.h"
|
||||
|
||||
|
||||
#else
|
||||
|
||||
class UdpStack
|
||||
{
|
||||
public:
|
||||
UdpStack(struct sockaddr_in &local) { return; }
|
||||
|
||||
/* from pqiNetListener */
|
||||
virtual bool resetAddress(struct sockaddr_in &local) { return false; }
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
/*******************************************************/
|
||||
|
||||
#include "pqi/pqimonitor.h"
|
||||
#include <iostream>
|
||||
|
||||
class rsUdpStack: public UdpStack, public pqiNetListener
|
||||
{
|
||||
public:
|
||||
rsUdpStack(struct sockaddr_in &local)
|
||||
:UdpStack(local) { return; }
|
||||
|
||||
/* from pqiNetListener */
|
||||
virtual bool resetListener(struct sockaddr_in &local)
|
||||
{
|
||||
std::cerr << "rsUdpStack::resetListener(" << local << ")";
|
||||
std::cerr << std::endl;
|
||||
return resetAddress(local);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif
|
|
@ -32,7 +32,7 @@
|
|||
* #include <arpa/inet.h>
|
||||
*/
|
||||
|
||||
#include "tou_net.h" /* for winsock.h -> htons etc */
|
||||
#include "util/rsnet.h" /* for winsock.h -> htons etc */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
|
|
@ -71,7 +71,7 @@ static const double RTT_ALPHA = 0.875;
|
|||
// platform independent fractional timestamp.
|
||||
static double getCurrentTS();
|
||||
|
||||
TcpStream::TcpStream(UdpSorter *lyr)
|
||||
TcpStream::TcpStream(UdpPeerReceiver *lyr)
|
||||
:inSize(0), outSizeRead(0), outSizeNet(0),
|
||||
state(TCP_CLOSED),
|
||||
inStreamActive(false),
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
*/
|
||||
|
||||
#include "tcppacket.h"
|
||||
#include "udpsorter.h"
|
||||
#include "udppeer.h"
|
||||
|
||||
#define MAX_SEG 1500
|
||||
#define TCP_MAX_SEQ UINT_MAX
|
||||
|
@ -73,7 +73,7 @@ class TcpStream: public UdpPeer
|
|||
public:
|
||||
/* Top-Level exposed */
|
||||
|
||||
TcpStream(UdpSorter *lyr);
|
||||
TcpStream(UdpPeerReceiver *udp);
|
||||
virtual ~TcpStream() { return; }
|
||||
|
||||
/* user interface */
|
||||
|
@ -230,8 +230,8 @@ uint32 int_rbytes();
|
|||
struct sockaddr_in peeraddr;
|
||||
bool peerKnown;
|
||||
|
||||
/* UdpSorter (has own Mutex!) */
|
||||
UdpSorter *udp;
|
||||
/* UdpPeerReceiver (has own Mutex!) */
|
||||
UdpPeerReceiver *udp;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -1,500 +0,0 @@
|
|||
/*
|
||||
* "$Id: test_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>
|
||||
|
||||
//#define USE_TCP_SOCKET
|
||||
|
||||
// for printing sockaddr
|
||||
#include "udplayer.h"
|
||||
|
||||
#ifndef USE_TCP_SOCKET
|
||||
#include "tou.h"
|
||||
#endif
|
||||
|
||||
/* shouldn't do this - but for convenience
|
||||
* using tou_net.h for universal fns
|
||||
* generally this should be only internal to libtou.h
|
||||
*
|
||||
* This includes the whole networking interface
|
||||
*/
|
||||
|
||||
#include "tou_net.h"
|
||||
|
||||
/* These three includes appear to work in both W & L.
|
||||
* and they shouldn't!!!! maybe cygwin is allowing it...
|
||||
* will only use them for tou test fns.
|
||||
*
|
||||
* they appear to provide getopt + read/write in windows.
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
/* This is a simple test to ensure that the tou behaviour
|
||||
* is almost identical to a standard tcp socket.
|
||||
*
|
||||
*/
|
||||
|
||||
int Check_Socket(int fd);
|
||||
|
||||
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 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;
|
||||
}
|
||||
|
||||
tounet_init();
|
||||
|
||||
/* setup the local/remote addresses.
|
||||
*/
|
||||
struct sockaddr_in laddr;
|
||||
struct sockaddr_in raddr;
|
||||
|
||||
laddr.sin_family = AF_INET;
|
||||
raddr.sin_family = AF_INET;
|
||||
|
||||
if ((!tounet_inet_aton(argv[optind], &(laddr.sin_addr))) ||
|
||||
(!tounet_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;
|
||||
|
||||
|
||||
#ifdef USE_TCP_SOCKET
|
||||
int sockfd = socket(PF_INET, SOCK_STREAM, 0);
|
||||
#else
|
||||
int sockfd = tou_socket(PF_INET, SOCK_STREAM, 0);
|
||||
#endif
|
||||
if (sockfd < 0)
|
||||
{
|
||||
std::cerr << "Failed to open socket!: ";
|
||||
#ifdef USE_TCP_SOCKET
|
||||
std::cerr << "Socket Error:" << errno << std::endl;
|
||||
#else
|
||||
std::cerr << "Socket Error:" << tou_errno(sockfd) << std::endl;
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
std::cerr << "Socket Created" << std::endl;
|
||||
|
||||
|
||||
/* make nonblocking */
|
||||
#ifdef USE_TCP_SOCKET
|
||||
int err = tounet_fcntl(sockfd,F_SETFL,O_NONBLOCK);
|
||||
#else
|
||||
int err = 0;
|
||||
#endif
|
||||
if (err < 0)
|
||||
{
|
||||
std::cerr << "Error: Cannot make socket NON-Blocking: ";
|
||||
std::cerr << err << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::cerr << "Socket Non-Blocking" << std::endl;
|
||||
|
||||
#ifdef USE_TCP_SOCKET
|
||||
err = bind(sockfd, (struct sockaddr *) &laddr, sizeof(laddr));
|
||||
#else
|
||||
err = tou_bind(sockfd, (struct sockaddr *) &laddr, sizeof(laddr));
|
||||
#endif
|
||||
if (err < 0)
|
||||
{
|
||||
std::cerr << "Error: Cannot bind socket: ";
|
||||
std::cerr << err << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::cerr << "Socket Bound to: " << laddr << std::endl;
|
||||
|
||||
if (toConnect)
|
||||
{
|
||||
std::cerr << "Socket Connecting to: " << raddr << std::endl;
|
||||
#ifdef USE_TCP_SOCKET
|
||||
err = connect(sockfd, (struct sockaddr *) &raddr, sizeof(raddr));
|
||||
#else
|
||||
err = tou_connect(sockfd, (struct sockaddr *) &raddr, sizeof(raddr), 30);
|
||||
#endif
|
||||
if (err < 0)
|
||||
{
|
||||
#ifndef USE_TCP_SOCKET
|
||||
errno = tou_errno(sockfd);
|
||||
#endif
|
||||
if (errno != EINPROGRESS)
|
||||
{
|
||||
std::cerr << "Cannot Connect!" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
#ifdef USE_TCP_SOCKET
|
||||
while(0 == (err = Check_Socket(sockfd)))
|
||||
#else
|
||||
while(0 == (err = tou_connected(sockfd)))
|
||||
#endif
|
||||
{
|
||||
std::cerr << "Waiting for Connect!" << std::endl;
|
||||
sleep(1);
|
||||
}
|
||||
if (err < 0)
|
||||
{
|
||||
std::cerr << "Connect Failed" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
// else connected!
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Socket Listening " << std::endl;
|
||||
/* listen */
|
||||
#ifdef USE_TCP_SOCKET
|
||||
err = listen(sockfd, 1);
|
||||
#else
|
||||
//err = tou_listen(sockfd, 1);
|
||||
err = tou_listenfor(sockfd,
|
||||
(struct sockaddr *) &raddr, sizeof(raddr));
|
||||
#endif
|
||||
|
||||
/* accept */
|
||||
struct sockaddr_in inaddr;
|
||||
socklen_t addrlen = sizeof(inaddr);
|
||||
int nsock;
|
||||
|
||||
#ifdef USE_TCP_SOCKET
|
||||
while(0 > (nsock = accept(sockfd,
|
||||
(struct sockaddr *) &inaddr, &addrlen)))
|
||||
#else
|
||||
while(0 > (nsock = tou_accept(sockfd,
|
||||
(struct sockaddr *) &inaddr, &addrlen)))
|
||||
#endif
|
||||
{
|
||||
#ifndef USE_TCP_SOCKET
|
||||
errno = tou_errno(sockfd);
|
||||
#endif
|
||||
if (errno != EAGAIN)
|
||||
{
|
||||
std::cerr << "Cannot Connect!" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
sleep(1);
|
||||
}
|
||||
/* changed sockfd */
|
||||
sockfd = nsock;
|
||||
std::cerr << "Socket Accepted from: " << inaddr << std::endl;
|
||||
}
|
||||
|
||||
std::cerr << "Socket Connected" << std::endl;
|
||||
|
||||
if (toConnect)
|
||||
{
|
||||
/* send data */
|
||||
int bufsize = 15011;
|
||||
char buffer[bufsize];
|
||||
int readsize = 0;
|
||||
|
||||
tounet_fcntl(0, F_SETFL, O_NONBLOCK);
|
||||
|
||||
bool done = false;
|
||||
bool blockread = false;
|
||||
while(!done)
|
||||
{
|
||||
sleep(1);
|
||||
//usleep(10000);
|
||||
//usleep(1000);
|
||||
if (blockread != true)
|
||||
{
|
||||
readsize = read(0, buffer, bufsize);
|
||||
}
|
||||
if (readsize == 0)
|
||||
{
|
||||
/* eof */
|
||||
done = true;
|
||||
}
|
||||
else if ((readsize == -1) && ( EAGAIN == errno ))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
/* now we write */
|
||||
#ifdef USE_TCP_SOCKET
|
||||
if (-1 == write(sockfd, buffer, readsize))
|
||||
#else
|
||||
if (-1 == tou_write(sockfd, buffer, readsize))
|
||||
#endif
|
||||
{
|
||||
//std::cerr << "Blocked Write!" << std::endl;
|
||||
#ifndef USE_TCP_SOCKET
|
||||
//std::cerr << "Error: " << tou_errno(sockfd) << std::endl;
|
||||
#endif
|
||||
blockread = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
blockread = false;
|
||||
totalwbytes += readsize;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USE_TCP_SOCKET
|
||||
close(sockfd);
|
||||
#else
|
||||
/* this is blocking??? */
|
||||
tou_close(sockfd);
|
||||
#endif
|
||||
|
||||
std::cerr << "Transfer Complete: " << totalwbytes << " bytes";
|
||||
std::cerr << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* recv data */
|
||||
int bufsize = 1523;
|
||||
char data[bufsize];
|
||||
tounet_fcntl(1,F_SETFL,O_NONBLOCK);
|
||||
while(1)
|
||||
{
|
||||
sleep(1);
|
||||
//usleep(10000);
|
||||
//usleep(1000);
|
||||
int writesize = bufsize;
|
||||
int ret;
|
||||
|
||||
#ifdef USE_TCP_SOCKET
|
||||
if (0 < (ret = read(sockfd, data, writesize)))
|
||||
#else
|
||||
if (0 < (ret = tou_read(sockfd, data, writesize)))
|
||||
#endif
|
||||
|
||||
{
|
||||
std::cerr << "TF(" << ret << ")" << std::endl;
|
||||
write(1, data, ret);
|
||||
totalrbytes += ret;
|
||||
}
|
||||
else if (ret == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
//std::cerr << "Blocked Read!" << std::endl;
|
||||
#ifndef USE_TCP_SOCKET
|
||||
//std::cerr << "Error: " << tou_errno(sockfd) << std::endl;
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USE_TCP_SOCKET
|
||||
close(sockfd);
|
||||
#else
|
||||
tou_close(sockfd);
|
||||
#endif
|
||||
|
||||
std::cerr << "Transfer complete :" << totalrbytes;
|
||||
std::cerr << " bytes" << std::endl;
|
||||
close(1);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef USE_TCP_SOCKET
|
||||
|
||||
|
||||
int Check_Socket(int fd)
|
||||
{
|
||||
std::cerr << "Check_Socket()" << std::endl;
|
||||
|
||||
std::cerr << "1) Checking with Select()" << std::endl;
|
||||
|
||||
fd_set ReadFDs, WriteFDs, ExceptFDs;
|
||||
FD_ZERO(&ReadFDs);
|
||||
FD_ZERO(&WriteFDs);
|
||||
FD_ZERO(&ExceptFDs);
|
||||
|
||||
FD_SET(fd, &ReadFDs);
|
||||
FD_SET(fd, &WriteFDs);
|
||||
FD_SET(fd, &ExceptFDs);
|
||||
|
||||
struct timeval timeout;
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_usec = 0;
|
||||
|
||||
int sr = 0;
|
||||
if (0 > (sr = select(fd + 1,
|
||||
&ReadFDs, &WriteFDs, &ExceptFDs, &timeout)))
|
||||
{
|
||||
std::cerr << "Check_Socket() Select ERROR: " << sr << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (FD_ISSET(fd, &ExceptFDs))
|
||||
{
|
||||
std::cerr << "Check_Socket() Exception on socket!" << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (FD_ISSET(fd, &WriteFDs))
|
||||
{
|
||||
std::cerr << "Check_Socket() Can Write!" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
// not ready return 0;
|
||||
std::cerr << "Check_Socket() Cannot Write!" << std::endl;
|
||||
std::cerr << "Check_Socket() Socket Not Ready!" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (FD_ISSET(fd, &ReadFDs))
|
||||
{
|
||||
std::cerr << "Check_Socket() Can Read!" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Check_Socket() Cannot Read!" << std::endl;
|
||||
std::cerr << "Check_Socket() Socket Not Ready!" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::cerr << "Select() Tests indicate Socket Good!" << std::endl;
|
||||
std::cerr << "2) Checking with getsockopt()" << std::endl;
|
||||
|
||||
int err = 1;
|
||||
socklen_t optlen = 4;
|
||||
if (0==getsockopt(fd, SOL_SOCKET, SO_ERROR, &err, &optlen))
|
||||
{
|
||||
std::cerr << "Check_Socket() getsockopt returned :" << err;
|
||||
std::cerr << ", optlen:" << optlen;
|
||||
std::cerr << std::endl;
|
||||
|
||||
if (err == 0)
|
||||
{
|
||||
std::cerr << "Check_Socket() getsockopt";
|
||||
std::cerr << " Indicates TCP Connection Complete:";
|
||||
std::cerr << std::endl;
|
||||
return 1;
|
||||
}
|
||||
else if (err == EINPROGRESS)
|
||||
{
|
||||
std::cerr << "Check_Socket() getsockopt";
|
||||
std::cerr << " Indicates TCP Connection INPROGRESS";
|
||||
std::cerr << std::endl;
|
||||
return 0;
|
||||
}
|
||||
else if ((err == ENETUNREACH) || (err == ETIMEDOUT))
|
||||
{
|
||||
std::cerr << "Check_Socket() getsockopt";
|
||||
std::cerr << " Indicates TCP Connection ENETUNREACH/ETIMEDOUT";
|
||||
std::cerr << std::endl;
|
||||
return -1;
|
||||
}
|
||||
else if ((err == EHOSTUNREACH) || (err == EHOSTDOWN))
|
||||
{
|
||||
std::cerr << "Check_Socket() getsockopt";
|
||||
std::cerr << " Indicates TCP Connection ENETUNREACH/ETIMEDOUT";
|
||||
std::cerr << std::endl;
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Check_Socket() getsockopt";
|
||||
std::cerr << " Indicates Other Error: " << err;
|
||||
std::cerr << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Check_Socket() getsockopt";
|
||||
std::cerr << " FAILED ";
|
||||
std::cerr << std::endl;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
|
||||
int Check_Socket(int fd)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -33,7 +33,7 @@ static const int kInitStreamTable = 5;
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "udplayer.h"
|
||||
#include "udp/udpstack.h"
|
||||
#include "tcpstream.h"
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
|
@ -55,115 +55,34 @@ typedef struct TcpOnUdp_t TcpOnUdp;
|
|||
static std::vector<TcpOnUdp *> tou_streams;
|
||||
|
||||
static int tou_inited = 0;
|
||||
static UdpSorter *udps = NULL;
|
||||
|
||||
|
||||
#include "udp/udpstack.h"
|
||||
#include "tcponudp/udppeer.h"
|
||||
|
||||
static UdpStack *udpstack = NULL;
|
||||
static UdpPeerReceiver *udps = NULL;
|
||||
|
||||
static int tou_tick_all();
|
||||
|
||||
/* tou_init - opens the udp port (universal bind) */
|
||||
int tou_init(const struct sockaddr *my_addr, socklen_t addrlen)
|
||||
int tou_init(UdpStack *stack)
|
||||
{
|
||||
if (tou_inited)
|
||||
{
|
||||
struct sockaddr_in *addr = (struct sockaddr_in *) my_addr;
|
||||
udps->resetAddress(*addr);
|
||||
if (!(udps->okay()))
|
||||
{
|
||||
std::cerr << "tou_init() FATAL ERROR: Cannot reset Udp Socket to: "
|
||||
<< rs_inet_ntoa(addr->sin_addr) << ":" << ntohs(addr->sin_port);
|
||||
std::cerr << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
tou_streams.resize(kInitStreamTable);
|
||||
|
||||
udps = new UdpSorter( *((struct sockaddr_in *) my_addr));
|
||||
|
||||
/* check the bind succeeded */
|
||||
if (!(udps->okay()))
|
||||
{
|
||||
delete (udps);
|
||||
udps = NULL;
|
||||
return -1;
|
||||
}
|
||||
udpstack = stack;
|
||||
udps = new UdpPeerReceiver(stack);
|
||||
stack->addReceiver(udps);
|
||||
|
||||
tou_inited = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* tou_stunpeer supply tou with stun peers. */
|
||||
int tou_stunpeer(const struct sockaddr *my_addr, socklen_t addrlen,
|
||||
const char *id)
|
||||
{
|
||||
if (!tou_inited)
|
||||
return -1;
|
||||
|
||||
udps->addStunPeer(*(struct sockaddr_in *) my_addr, id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tou_stunkeepalive(int required)
|
||||
{
|
||||
if (!tou_inited)
|
||||
return -1;
|
||||
|
||||
udps->setStunKeepAlive(required);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int tou_getstunpeer(int i, struct sockaddr *remote_addr, socklen_t *raddrlen,
|
||||
struct sockaddr *ext_addr, socklen_t *eaddrlen,
|
||||
uint32_t *failCount, time_t *lastSend)
|
||||
{
|
||||
if (!tou_inited)
|
||||
return -1;
|
||||
|
||||
std::string id;
|
||||
|
||||
bool ret = udps->getStunPeer(i, id,
|
||||
*((struct sockaddr_in *) remote_addr),
|
||||
*((struct sockaddr_in *) ext_addr),
|
||||
*failCount, *lastSend);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int tou_needstunpeers()
|
||||
{
|
||||
if (!tou_inited)
|
||||
return -1;
|
||||
|
||||
if (udps->needStunPeers())
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int tou_tick_stunkeepalive()
|
||||
{
|
||||
if (!tou_inited)
|
||||
return -1;
|
||||
|
||||
udps->tick();
|
||||
return 1;
|
||||
}
|
||||
|
||||
int tou_extaddr(struct sockaddr *ext_addr, socklen_t *addrlen, uint8_t *stable)
|
||||
{
|
||||
if (!tou_inited)
|
||||
return -1;
|
||||
|
||||
if (udps->externalAddr(*(struct sockaddr_in *) ext_addr, *stable))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* open - which does nothing */
|
||||
int tou_socket(int /*domain*/, int /*type*/, int /*protocol*/)
|
||||
|
|
|
@ -53,39 +53,18 @@
|
|||
/* 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.
|
||||
*/
|
||||
|
||||
class UdpStack;
|
||||
int tou_init(UdpStack *stack);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* The modification to a single UDP socket means
|
||||
* that the structure of the TOU interface must be changed.
|
||||
*
|
||||
* Init:
|
||||
* (1) choose our local address. (a universal bind)
|
||||
* int tou_init(const struct sockaddr *my_addr);
|
||||
* (2) query if we have determined our external address.
|
||||
* int tou_extaddr(struct sockaddr *ext_addr, socklen_t *addrlen);
|
||||
* (3) offer more stunpeers, for external address determination.
|
||||
* int tou_stunpeer(const struct sockaddr *ext_addr, socklen_t addrlen, const char *id);
|
||||
* (4) repeat (2)+(3) until a valid extaddr is returned.
|
||||
* (5) if stunkeepalive is required, then periodically send out
|
||||
* stun packets to maintain external firewall port.
|
||||
*
|
||||
*/
|
||||
|
||||
int tou_init(const struct sockaddr *my_addr, socklen_t addrlen);
|
||||
int tou_extaddr(struct sockaddr *ext_addr, socklen_t *addrlen, uint8_t *stable);
|
||||
int tou_stunpeer(const struct sockaddr *ext_addr, socklen_t addrlen, const char *id);
|
||||
int tou_stunkeepalive(int required);
|
||||
int tou_tick_stunkeepalive();
|
||||
|
||||
int tou_getstunpeer(int i, struct sockaddr *remote_addr, socklen_t *raddrlen,
|
||||
struct sockaddr *ext_addr, socklen_t *eaddrlen,
|
||||
uint32_t *failCount, time_t *lastSend);
|
||||
int tou_needstunpeers();
|
||||
|
||||
|
||||
/* 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().
|
||||
|
|
|
@ -1,75 +0,0 @@
|
|||
/*
|
||||
* "$Id: tou_errno.h,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".
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef TOU_ERRNO_HEADER
|
||||
#define TOU_ERRNO_HEADER
|
||||
|
||||
/* C Interface */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*******
|
||||
* This defines the unix errno's for windows, these are
|
||||
* needed to determine error types, these are defined
|
||||
* to be the same as the unix ones.
|
||||
*/
|
||||
|
||||
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
|
||||
#ifdef WINDOWS_SYS
|
||||
|
||||
#define EAGAIN 11
|
||||
#define EWOULDBLOCK EAGAIN
|
||||
|
||||
#define EUSERS 87
|
||||
#define ENOTSOCK 88
|
||||
|
||||
#define EOPNOTSUPP 95
|
||||
|
||||
#define EADDRINUSE 98
|
||||
#define EADDRNOTAVAIL 99
|
||||
#define ENETDOWN 100
|
||||
#define ENETUNREACH 101
|
||||
|
||||
#define ECONNRESET 104
|
||||
|
||||
#define ETIMEDOUT 110
|
||||
#define ECONNREFUSED 111
|
||||
#define EHOSTDOWN 112
|
||||
#define EHOSTUNREACH 113
|
||||
#define EALREADY 114
|
||||
#define EINPROGRESS 115
|
||||
|
||||
|
||||
#endif
|
||||
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* C Interface */
|
||||
#endif
|
||||
|
||||
#endif /* TOU_ERRNO_HEADER */
|
|
@ -1,346 +0,0 @@
|
|||
/*
|
||||
* "$Id: tou_net.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 "tou_net.h"
|
||||
|
||||
|
||||
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
|
||||
#ifndef WINDOWS_SYS
|
||||
|
||||
/* Unix Version is easy -> just call the unix fn
|
||||
*/
|
||||
|
||||
#include <unistd.h> /* for close definition */
|
||||
|
||||
/* the universal interface */
|
||||
int tounet_init() { return 0; }
|
||||
int tounet_errno() { return errno; }
|
||||
|
||||
|
||||
/* check if we can modify the TTL on a UDP packet */
|
||||
int tounet_checkTTL(int fd) { return 1;}
|
||||
|
||||
|
||||
int tounet_inet_aton(const char *name, struct in_addr *addr)
|
||||
{
|
||||
return inet_aton(name, addr);
|
||||
}
|
||||
|
||||
int tounet_close(int fd) { return close(fd); }
|
||||
|
||||
int tounet_socket(int domain, int type, int protocol)
|
||||
{
|
||||
return socket(domain, type, protocol);
|
||||
}
|
||||
|
||||
int tounet_bind(int sockfd, const struct sockaddr *my_addr, socklen_t addrlen)
|
||||
{
|
||||
return bind(sockfd,my_addr,addrlen);
|
||||
}
|
||||
|
||||
int tounet_fcntl(int fd, int cmd, long arg)
|
||||
{
|
||||
return fcntl(fd, cmd, arg);
|
||||
}
|
||||
|
||||
int tounet_setsockopt(int s, int level, int optname,
|
||||
const void *optval, socklen_t optlen)
|
||||
{
|
||||
return setsockopt(s, level, optname, optval, optlen);
|
||||
}
|
||||
|
||||
ssize_t tounet_recvfrom(int s, void *buf, size_t len, int flags,
|
||||
struct sockaddr *from, socklen_t *fromlen)
|
||||
{
|
||||
return recvfrom(s, buf, len, flags, from, fromlen);
|
||||
}
|
||||
|
||||
ssize_t tounet_sendto(int s, const void *buf, size_t len, int flags,
|
||||
const struct sockaddr *to, socklen_t tolen)
|
||||
{
|
||||
return sendto(s, buf, len, flags, to, tolen);
|
||||
}
|
||||
|
||||
|
||||
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
|
||||
#else /* WINDOWS OS */
|
||||
|
||||
#include <iostream>
|
||||
|
||||
/* error handling */
|
||||
int tounet_int_errno;
|
||||
|
||||
int tounet_errno()
|
||||
{
|
||||
return tounet_int_errno;
|
||||
}
|
||||
|
||||
int tounet_init()
|
||||
{
|
||||
std::cerr << "tounet_init()" << std::endl;
|
||||
tounet_int_errno = 0;
|
||||
|
||||
// Windows Networking Init.
|
||||
WORD wVerReq = MAKEWORD(2,2);
|
||||
WSADATA wsaData;
|
||||
|
||||
if (0 != WSAStartup(wVerReq, &wsaData))
|
||||
{
|
||||
std::cerr << "Failed to Startup Windows Networking";
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Started Windows Networking";
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* check if we can modify the TTL on a UDP packet */
|
||||
int tounet_checkTTL(int fd)
|
||||
{
|
||||
std::cerr << "tounet_checkTTL()" << std::endl;
|
||||
int optlen = 4;
|
||||
char optval[optlen];
|
||||
|
||||
int ret = getsockopt(fd, IPPROTO_IP, IP_TTL, optval, &optlen);
|
||||
//int ret = getsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL, optval, &optlen);
|
||||
if (ret == SOCKET_ERROR)
|
||||
{
|
||||
ret = -1;
|
||||
tounet_int_errno = tounet_w2u_errno(WSAGetLastError());
|
||||
std::cerr << "tounet_checkTTL() Failed!";
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "tounet_checkTTL() :";
|
||||
std::cerr << (int) optval[0] << ":";
|
||||
std::cerr << (int) optval[1] << ":";
|
||||
std::cerr << (int) optval[2] << ":";
|
||||
std::cerr << (int) optval[3] << ": RET: ";
|
||||
std::cerr << ret << ":";
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int tounet_close(int fd)
|
||||
{
|
||||
std::cerr << "tounet_close()" << std::endl;
|
||||
return closesocket(fd);
|
||||
}
|
||||
|
||||
int tounet_socket(int domain, int type, int protocol)
|
||||
{
|
||||
int osock = socket(domain, type, protocol);
|
||||
std::cerr << "tounet_socket()" << std::endl;
|
||||
|
||||
if ((unsigned) osock == INVALID_SOCKET)
|
||||
{
|
||||
// Invalidate socket Unix style.
|
||||
osock = -1;
|
||||
tounet_int_errno = tounet_w2u_errno(WSAGetLastError());
|
||||
}
|
||||
tounet_checkTTL(osock);
|
||||
return osock;
|
||||
}
|
||||
|
||||
int tounet_bind(int sockfd, const struct sockaddr *my_addr, socklen_t addrlen)
|
||||
{
|
||||
std::cerr << "tounet_bind()" << std::endl;
|
||||
int ret = bind(sockfd,my_addr,addrlen);
|
||||
if (ret != 0)
|
||||
{
|
||||
/* store unix-style error
|
||||
*/
|
||||
|
||||
ret = -1;
|
||||
tounet_int_errno = tounet_w2u_errno(WSAGetLastError());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int tounet_fcntl(int fd, int cmd, long arg)
|
||||
{
|
||||
int ret;
|
||||
|
||||
unsigned long int on = 1;
|
||||
std::cerr << "tounet_fcntl()" << std::endl;
|
||||
|
||||
/* can only do NONBLOCK at the moment */
|
||||
if ((cmd != F_SETFL) || (arg != O_NONBLOCK))
|
||||
{
|
||||
std::cerr << "tounet_fcntl() limited to fcntl(fd, F_SETFL, O_NONBLOCK)";
|
||||
std::cerr << std::endl;
|
||||
tounet_int_errno = EOPNOTSUPP;
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = ioctlsocket(fd, FIONBIO, &on);
|
||||
|
||||
if (ret != 0)
|
||||
{
|
||||
/* store unix-style error
|
||||
*/
|
||||
|
||||
ret = -1;
|
||||
tounet_int_errno = tounet_w2u_errno(WSAGetLastError());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int tounet_setsockopt(int s, int level, int optname,
|
||||
const void *optval, socklen_t optlen)
|
||||
{
|
||||
std::cerr << "tounet_setsockopt() val:" << *((int *) optval) << std::endl;
|
||||
std::cerr << "tounet_setsockopt() len:" << optlen << std::endl;
|
||||
if ((level != IPPROTO_IP) || (optname != IP_TTL))
|
||||
{
|
||||
std::cerr << "tounet_setsockopt() limited to ";
|
||||
std::cerr << "setsockopt(fd, IPPROTO_IP, IP_TTL, ....)";
|
||||
std::cerr << std::endl;
|
||||
tounet_int_errno = EOPNOTSUPP;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int ret = setsockopt(s, level, optname, (const char *) optval, optlen);
|
||||
//int ret = setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL, (const char *) optval, optlen);
|
||||
if (ret == SOCKET_ERROR)
|
||||
{
|
||||
ret = -1;
|
||||
tounet_int_errno = tounet_w2u_errno(WSAGetLastError());
|
||||
}
|
||||
tounet_checkTTL(s);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ssize_t tounet_recvfrom(int s, void *buf, size_t len, int flags,
|
||||
struct sockaddr *from, socklen_t *fromlen)
|
||||
{
|
||||
std::cerr << "tounet_recvfrom()" << std::endl;
|
||||
int ret = recvfrom(s, (char *) buf, len, flags, from, fromlen);
|
||||
if (ret == SOCKET_ERROR)
|
||||
{
|
||||
ret = -1;
|
||||
tounet_int_errno = tounet_w2u_errno(WSAGetLastError());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
ssize_t tounet_sendto(int s, const void *buf, size_t len, int flags,
|
||||
const struct sockaddr *to, socklen_t tolen)
|
||||
{
|
||||
std::cerr << "tounet_sendto()" << std::endl;
|
||||
int ret = sendto(s, (const char *) buf, len, flags, to, tolen);
|
||||
if (ret == SOCKET_ERROR)
|
||||
{
|
||||
ret = -1;
|
||||
tounet_int_errno = tounet_w2u_errno(WSAGetLastError());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int tounet_w2u_errno(int err)
|
||||
{
|
||||
/* switch */
|
||||
std::cerr << "tou_net_w2u_errno(" << err << ")" << std::endl;
|
||||
switch(err)
|
||||
{
|
||||
case WSAEINPROGRESS:
|
||||
return EINPROGRESS;
|
||||
break;
|
||||
case WSAEWOULDBLOCK:
|
||||
return EINPROGRESS;
|
||||
break;
|
||||
case WSAENETUNREACH:
|
||||
return ENETUNREACH;
|
||||
break;
|
||||
case WSAETIMEDOUT:
|
||||
return ETIMEDOUT;
|
||||
break;
|
||||
case WSAEHOSTDOWN:
|
||||
return EHOSTDOWN;
|
||||
break;
|
||||
case WSAECONNREFUSED:
|
||||
return ECONNREFUSED;
|
||||
break;
|
||||
case WSAEADDRINUSE:
|
||||
return EADDRINUSE;
|
||||
break;
|
||||
case WSAEUSERS:
|
||||
return EUSERS;
|
||||
break;
|
||||
/* This one is returned for UDP recvfrom, when nothing there
|
||||
* but not a real error... translate into EINPROGRESS
|
||||
*/
|
||||
case WSAECONNRESET:
|
||||
std::cerr << "tou_net_w2u_errno(" << err << ")";
|
||||
std::cerr << " = WSAECONNRESET ---> EINPROGRESS";
|
||||
std::cerr << std::endl;
|
||||
return EINPROGRESS;
|
||||
break;
|
||||
/***
|
||||
*
|
||||
case WSAECONNRESET:
|
||||
return ECONNRESET;
|
||||
break;
|
||||
*
|
||||
***/
|
||||
|
||||
default:
|
||||
std::cerr << "tou_net_w2u_errno(" << err << ") Unknown";
|
||||
std::cerr << std::endl;
|
||||
break;
|
||||
}
|
||||
|
||||
return ECONNREFUSED; /* sensible default? */
|
||||
}
|
||||
|
||||
int tounet_inet_aton(const char *name, struct in_addr *addr)
|
||||
{
|
||||
return (((*addr).s_addr = inet_addr(name)) != INADDR_NONE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void sleep(int sec)
|
||||
{
|
||||
Sleep(sec * 1000);
|
||||
}
|
||||
|
||||
void usleep(int usec)
|
||||
{
|
||||
Sleep(usec / 1000);
|
||||
}
|
||||
|
||||
#endif
|
||||
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
|
||||
|
|
@ -1,131 +0,0 @@
|
|||
/*
|
||||
* "$Id: tou_net.h,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".
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef TOU_UNIVERSAL_NETWORK_HEADER
|
||||
#define TOU_UNIVERSAL_NETWORK_HEADER
|
||||
|
||||
/* Some Types need to be defined before the interface can be declared
|
||||
*/
|
||||
|
||||
#include "util/rsnet.h"
|
||||
|
||||
/* C Interface */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*******
|
||||
* This defines a (unix-like) universal networking layer
|
||||
* that should function on both windows and unix. (C - interface)
|
||||
*
|
||||
* This is of course only a subset of the full interface.
|
||||
* functions required are:
|
||||
*
|
||||
* int tounet_close(int fd);
|
||||
* int tounet_socket(int domain, int type, int protocol);
|
||||
* int tounet_bind(int sockfd, const struct sockaddr *my_addr,
|
||||
* socklen_t addrlen);
|
||||
* int tounet_fcntl(int fd, int cmd, long arg);
|
||||
* int tounet_setsockopt(int s, int level, int optname,
|
||||
* const void *optval, socklen_t optlen);
|
||||
* ssize_t tounet_recvfrom(int s, void *buf, size_t len, int flags,
|
||||
* struct sockaddr *from, socklen_t *fromlen);
|
||||
* ssize_t tounet_sendto(int s, const void *buf, size_t len, int flags,
|
||||
* const struct sockaddr *to, socklen_t tolen);
|
||||
*
|
||||
* There are some non-standard ones as well:
|
||||
* int tounet_errno(); for internal networking errors
|
||||
* int tounet_init(); required for windows
|
||||
* int tounet_checkTTL(); a check if we can modify the ttl
|
||||
*/
|
||||
|
||||
|
||||
/* the universal interface */
|
||||
int tounet_errno(); /* for internal networking errors */
|
||||
int tounet_init(); /* required for windows */
|
||||
int tounet_close(int fd);
|
||||
int tounet_socket(int domain, int type, int protocol);
|
||||
int tounet_bind(int sockfd, const struct sockaddr *my_addr, socklen_t addrlen);
|
||||
int tounet_fcntl(int fd, int cmd, long arg);
|
||||
int tounet_setsockopt(int s, int level, int optname,
|
||||
const void *optval, socklen_t optlen);
|
||||
ssize_t tounet_recvfrom(int s, void *buf, size_t len, int flags,
|
||||
struct sockaddr *from, socklen_t *fromlen);
|
||||
ssize_t tounet_sendto(int s, const void *buf, size_t len, int flags,
|
||||
const struct sockaddr *to, socklen_t tolen);
|
||||
|
||||
/* address filling */
|
||||
int tounet_inet_aton(const char *name, struct in_addr *addr);
|
||||
/* check if we can modify the TTL on a UDP packet */
|
||||
int tounet_checkTTL(int fd);
|
||||
|
||||
|
||||
|
||||
/* Extra stuff to declare for windows error handling (mimics unix errno)
|
||||
*/
|
||||
|
||||
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
|
||||
#ifdef WINDOWS_SYS
|
||||
|
||||
// Some Network functions that are missing from windows.
|
||||
//in_addr_t inet_netof(struct in_addr addr);
|
||||
//in_addr_t inet_network(char *inet_name);
|
||||
//int inet_aton(const char *name, struct in_addr *addr);
|
||||
|
||||
|
||||
// definitions for fcntl (NON_BLOCK) (random?)
|
||||
#define F_SETFL 0x1010
|
||||
#define O_NONBLOCK 0x0100
|
||||
|
||||
// definitions for setsockopt (TTL) (random?)
|
||||
//#define IPPROTO_IP 0x0011
|
||||
//#define IP_TTL 0x0110
|
||||
|
||||
/* define the Unix Error Codes that we use...
|
||||
* NB. we should make the same, but not necessary
|
||||
*/
|
||||
|
||||
#include "tou_errno.h"
|
||||
|
||||
int tounet_w2u_errno(int error);
|
||||
|
||||
/* also put the sleep commands in here (where else to go)
|
||||
* ms uses millisecs.
|
||||
* void Sleep(int ms);
|
||||
*/
|
||||
void sleep(int sec);
|
||||
//void usleep(int usec);
|
||||
|
||||
#endif
|
||||
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* C Interface */
|
||||
#endif
|
||||
|
||||
#endif /* TOU_UNIVERSAL_NETWORK_HEADER */
|
|
@ -1,289 +0,0 @@
|
|||
/*
|
||||
* "$Id: udp_server.cc,v 1.4 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 "udplayer.h"
|
||||
#include "tcpstream.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
/* unix only
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
*/
|
||||
|
||||
#include "tou_net.h"
|
||||
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
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;
|
||||
|
||||
while(-1 != (c = getopt(argc, argv, "f:pco")))
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case 'p':
|
||||
isProxy = true;
|
||||
break;
|
||||
case 'c':
|
||||
toConnect = true;
|
||||
break;
|
||||
case 'o':
|
||||
stayOpen = true;
|
||||
break;
|
||||
case 'f':
|
||||
/* this can only work when the define below exists in tcpstream */
|
||||
#ifdef DEBUG_TCP_STREAM_EXTRA
|
||||
setupBinaryCheck(std::string(optarg));
|
||||
#else
|
||||
std::cerr << "Binary Check no Enabled!" << std::endl;
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
usage(argv[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (argc-optind < 4)
|
||||
{
|
||||
usage(argv[0]);
|
||||
return 1;
|
||||
}
|
||||
/* setup the local/remote addresses.
|
||||
*/
|
||||
|
||||
tounet_init();
|
||||
|
||||
struct sockaddr_in laddr;
|
||||
struct sockaddr_in raddr;
|
||||
|
||||
laddr.sin_family = AF_INET;
|
||||
raddr.sin_family = AF_INET;
|
||||
|
||||
if ((!tounet_inet_aton(argv[optind], &(laddr.sin_addr))) ||
|
||||
(!tounet_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;
|
||||
|
||||
UdpSorter udps(laddr);
|
||||
if (!udps.okay())
|
||||
{
|
||||
std::cerr << "UdpSorter not Okay (Cannot Open Local Address): " << laddr << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
TcpStream tcp(&udps);
|
||||
udps.addUdpPeer(&tcp, raddr);
|
||||
|
||||
if (toConnect)
|
||||
{
|
||||
tcp.connect(raddr, 30);
|
||||
}
|
||||
else
|
||||
{
|
||||
tcp.listenfor(raddr);
|
||||
}
|
||||
|
||||
while(!tcp.isConnected())
|
||||
{
|
||||
sleep(1);
|
||||
std::cerr << "Waiting for TCP to Connect!" << std::endl;
|
||||
udps.status(std::cerr);
|
||||
tcp.status(std::cerr);
|
||||
tcp.tick();
|
||||
}
|
||||
std::cerr << "TCP Connected***************************" << std::endl;
|
||||
udps.status(std::cerr);
|
||||
tcp.status(std::cerr);
|
||||
std::cerr << "TCP Connected***************************" << std::endl;
|
||||
|
||||
int count = 1;
|
||||
|
||||
if (toConnect)
|
||||
{
|
||||
/* send data */
|
||||
int bufsize = 51;
|
||||
char buffer[bufsize];
|
||||
int readsize = 0;
|
||||
|
||||
tounet_fcntl(0, F_SETFL, O_NONBLOCK);
|
||||
|
||||
bool done = false;
|
||||
bool blockread = false;
|
||||
while(!done)
|
||||
{
|
||||
//sleep(1);
|
||||
usleep(100000);
|
||||
//usleep(1000);
|
||||
if (blockread != true)
|
||||
{
|
||||
readsize = read(0, buffer, bufsize);
|
||||
}
|
||||
if (readsize == 0)
|
||||
{
|
||||
/* eof */
|
||||
done = true;
|
||||
}
|
||||
else if ((readsize == -1) && ( EAGAIN == errno ))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
/* now we write */
|
||||
if (-1 == tcp.write(buffer, readsize))
|
||||
blockread = true;
|
||||
else
|
||||
blockread = false;
|
||||
|
||||
|
||||
tcp.tick();
|
||||
if (count++ % 10 == 0)
|
||||
{
|
||||
std::cerr << "******************************************" << std::endl;
|
||||
tcp.status(std::cerr);
|
||||
}
|
||||
}
|
||||
|
||||
tcp.closeWrite();
|
||||
|
||||
while(!tcp.widle())
|
||||
{
|
||||
//sleep(1);
|
||||
usleep(100000);
|
||||
//usleep(1000);
|
||||
tcp.tick();
|
||||
if (count++ % 10 == 0)
|
||||
{
|
||||
std::cerr << "Waiting for Idle()" << std::endl;
|
||||
std::cerr << "******************************************" << std::endl;
|
||||
tcp.status(std::cerr);
|
||||
}
|
||||
}
|
||||
|
||||
std::cerr << "Transfer Complete: " << tcp.wbytes() << " bytes";
|
||||
std::cerr << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* recv data */
|
||||
int bufsize = 1523;
|
||||
char data[bufsize];
|
||||
tounet_fcntl(1,F_SETFL,O_NONBLOCK);
|
||||
while(1)
|
||||
{
|
||||
//sleep(1);
|
||||
usleep(100000);
|
||||
//usleep(1000);
|
||||
//int writesize = bufsize;
|
||||
int ret;
|
||||
if (0 < (ret = tcp.read(data, bufsize)))
|
||||
{
|
||||
std::cerr << "TF(" << ret << ")" << std::endl;
|
||||
write(1, data, ret);
|
||||
}
|
||||
else if (ret == 0)
|
||||
{
|
||||
/* completed transfer */
|
||||
std::cerr << "Transfer complete :" << tcp.rbytes();
|
||||
std::cerr << " bytes" << std::endl;
|
||||
break;
|
||||
}
|
||||
|
||||
tcp.tick();
|
||||
if (count++ % 10 == 0)
|
||||
{
|
||||
std::cerr << "******************************************" << std::endl;
|
||||
tcp.status(std::cerr);
|
||||
}
|
||||
if ((!stayOpen) && tcp.ridle())
|
||||
{
|
||||
std::cerr << "Transfer Idle after " << tcp.rbytes();
|
||||
std::cerr << " bytes" << std::endl;
|
||||
close(1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
tcp.closeWrite();
|
||||
|
||||
/* tick for a bit */
|
||||
while((stayOpen) || (!tcp.ridle()))
|
||||
{
|
||||
tcp.tick();
|
||||
//sleep(1);
|
||||
usleep(100000);
|
||||
//usleep(1000);
|
||||
if (count++ % 10 == 0)
|
||||
{
|
||||
std::cerr << "Waiting for Idle()" << std::endl;
|
||||
std::cerr << "******************************************" << std::endl;
|
||||
tcp.status(std::cerr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ((!stayOpen) && tcp.ridle())
|
||||
{
|
||||
//std::cerr << "Transfer complete :" << tcp.rbytes();
|
||||
//std::cerr << " bytes" << std::endl;
|
||||
close(1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,501 +0,0 @@
|
|||
/*
|
||||
* "$Id: udplayer.cc,v 1.8 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 "udplayer.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/*
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
*/
|
||||
|
||||
/***
|
||||
* #define DEBUG_UDP_LAYER 1
|
||||
***/
|
||||
|
||||
static const int UDP_DEF_TTL = 64;
|
||||
|
||||
/* NB: This #define makes the listener open 0.0.0.0:X port instead
|
||||
* of a specific port - this might help retroshare work on PCs with
|
||||
* multiple interfaces or unique network setups.
|
||||
* #define OPEN_UNIVERSAL_PORT 1
|
||||
*
|
||||
* This is also defined in pqissllistener (for TCP port).
|
||||
*/
|
||||
|
||||
#define OPEN_UNIVERSAL_PORT 1
|
||||
|
||||
|
||||
class udpPacket
|
||||
{
|
||||
public:
|
||||
udpPacket(struct sockaddr_in *addr, void *dta, int dlen)
|
||||
:raddr(*addr), len(dlen)
|
||||
{
|
||||
data = malloc(len);
|
||||
memcpy(data, dta, len);
|
||||
}
|
||||
|
||||
~udpPacket()
|
||||
{
|
||||
if (data)
|
||||
{
|
||||
free(data);
|
||||
data = NULL;
|
||||
len = 0;
|
||||
}
|
||||
}
|
||||
|
||||
struct sockaddr_in raddr;
|
||||
void *data;
|
||||
int len;
|
||||
};
|
||||
|
||||
|
||||
|
||||
bool operator==(const struct sockaddr_in &addr, const struct sockaddr_in &addr2)
|
||||
{
|
||||
if (addr.sin_family != addr2.sin_family)
|
||||
return false;
|
||||
if (addr.sin_addr.s_addr != addr2.sin_addr.s_addr)
|
||||
return false;
|
||||
if (addr.sin_port != addr2.sin_port)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool operator<(const struct sockaddr_in &addr, const struct sockaddr_in &addr2)
|
||||
{
|
||||
if (addr.sin_family != addr2.sin_family)
|
||||
return (addr.sin_family < addr2.sin_family);
|
||||
if (addr.sin_addr.s_addr != addr2.sin_addr.s_addr)
|
||||
return (addr.sin_addr.s_addr < addr2.sin_addr.s_addr);
|
||||
if (addr.sin_port != addr2.sin_port)
|
||||
return (addr.sin_port < addr2.sin_port);
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string printPkt(void *d, int size)
|
||||
{
|
||||
std::ostringstream out;
|
||||
out << "Packet:" << "**********************";
|
||||
for(int i = 0; i < size; i++)
|
||||
{
|
||||
if (i % 16 == 0)
|
||||
out << std::endl;
|
||||
out << std::hex << std::setw(2) << (unsigned int) ((unsigned char *) d)[i] << " ";
|
||||
}
|
||||
out << std::endl << "**********************";
|
||||
out << std::endl;
|
||||
return out.str();
|
||||
}
|
||||
|
||||
|
||||
std::string printPktOffset(unsigned int offset, void *d, unsigned int size)
|
||||
{
|
||||
std::ostringstream out;
|
||||
out << "Packet:" << "**********************";
|
||||
out << std::endl;
|
||||
out << "Offset: " << std::hex << offset << " -> " << offset + size;
|
||||
out << std::endl;
|
||||
out << "Packet:" << "**********************";
|
||||
|
||||
unsigned int j = offset % 16;
|
||||
if (j != 0)
|
||||
{
|
||||
out << std::endl;
|
||||
out << std::hex << std::setw(6) << (unsigned int) offset - j;
|
||||
out << ": ";
|
||||
for(unsigned int i = 0; i < j; i++)
|
||||
{
|
||||
out << "xx ";
|
||||
}
|
||||
}
|
||||
for(unsigned int i = offset; i < offset + size; i++)
|
||||
{
|
||||
if (i % 16 == 0)
|
||||
{
|
||||
out << std::endl;
|
||||
out << std::hex << std::setw(6) << (unsigned int) i;
|
||||
out << ": ";
|
||||
}
|
||||
out << std::hex << std::setw(2) << (unsigned int) ((unsigned char *) d)[i-offset] << " ";
|
||||
}
|
||||
out << std::endl << "**********************";
|
||||
out << std::endl;
|
||||
return out.str();
|
||||
}
|
||||
|
||||
|
||||
|
||||
UdpLayer::UdpLayer(UdpReceiver *udpr, struct sockaddr_in &local)
|
||||
:recv(udpr), laddr(local), errorState(0), ttl(UDP_DEF_TTL)
|
||||
{
|
||||
openSocket();
|
||||
return;
|
||||
}
|
||||
|
||||
int UdpLayer::status(std::ostream &out)
|
||||
{
|
||||
out << "UdpLayer::status()" << std::endl;
|
||||
out << "localaddr: " << laddr << std::endl;
|
||||
out << "sockfd: " << sockfd << std::endl;
|
||||
out << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int UdpLayer::reset(struct sockaddr_in &local)
|
||||
{
|
||||
#ifdef DEBUG_UDP_LAYER
|
||||
std::cerr << "UdpLayer::reset()" << std::endl;
|
||||
#endif
|
||||
|
||||
/* stop the old thread */
|
||||
{
|
||||
RsStackMutex stack(sockMtx); /********** LOCK MUTEX *********/
|
||||
#ifdef DEBUG_UDP_LAYER
|
||||
std::cerr << "UdpLayer::reset() setting stopThread flag" << std::endl;
|
||||
#endif
|
||||
stopThread = true;
|
||||
}
|
||||
#ifdef DEBUG_UDP_LAYER
|
||||
std::cerr << "UdpLayer::reset() joining" << std::endl;
|
||||
#endif
|
||||
|
||||
join();
|
||||
|
||||
#ifdef DEBUG_UDP_LAYER
|
||||
std::cerr << "UdpLayer::reset() closing socket" << std::endl;
|
||||
#endif
|
||||
close();
|
||||
|
||||
#ifdef DEBUG_UDP_LAYER
|
||||
std::cerr << "UdpLayer::reset() resetting variables" << std::endl;
|
||||
#endif
|
||||
laddr = local;
|
||||
errorState = 0;
|
||||
ttl = UDP_DEF_TTL;
|
||||
|
||||
#ifdef DEBUG_UDP_LAYER
|
||||
std::cerr << "UdpLayer::reset() opening socket" << std::endl;
|
||||
#endif
|
||||
openSocket();
|
||||
|
||||
return 1 ;
|
||||
}
|
||||
|
||||
|
||||
int UdpLayer::close()
|
||||
{
|
||||
/* close socket if open */
|
||||
sockMtx.lock(); /********** LOCK MUTEX *********/
|
||||
|
||||
if (sockfd > 0)
|
||||
{
|
||||
tounet_close(sockfd);
|
||||
}
|
||||
|
||||
sockMtx.unlock(); /******** UNLOCK MUTEX *********/
|
||||
return 1;
|
||||
}
|
||||
|
||||
void UdpLayer::run()
|
||||
{
|
||||
return recv_loop();
|
||||
}
|
||||
|
||||
/* higher level interface */
|
||||
void UdpLayer::recv_loop()
|
||||
{
|
||||
int maxsize = 16000;
|
||||
void *inbuf = malloc(maxsize);
|
||||
|
||||
int status;
|
||||
struct timeval timeout;
|
||||
|
||||
while(m_bRun)
|
||||
{
|
||||
/* select on the socket TODO */
|
||||
fd_set rset;
|
||||
for(;;)
|
||||
{
|
||||
/* check if we need to stop */
|
||||
bool toStop = false;
|
||||
{
|
||||
RsStackMutex stack(sockMtx); /********** LOCK MUTEX *********/
|
||||
toStop = stopThread;
|
||||
}
|
||||
|
||||
if (toStop)
|
||||
{
|
||||
std::cerr << "UdpLayer::recv_loop() stopping thread" << std::endl;
|
||||
stop();
|
||||
}
|
||||
|
||||
FD_ZERO(&rset);
|
||||
FD_SET(sockfd, &rset);
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_usec = 500000; /* 500 ms timeout */
|
||||
status = select(sockfd+1, &rset, NULL, NULL, &timeout);
|
||||
if (status > 0)
|
||||
{
|
||||
break; /* data available, go read it */
|
||||
}
|
||||
else if (status < 0)
|
||||
{
|
||||
#ifdef DEBUG_UDP_LAYER
|
||||
std::cerr << "UdpLayer::recv_loop() Error: " << tounet_errno() << std::endl;
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
int nsize = maxsize;
|
||||
struct sockaddr_in from;
|
||||
if (0 < receiveUdpPacket(inbuf, &nsize, from))
|
||||
{
|
||||
#ifdef DEBUG_UDP_LAYER
|
||||
std::cerr << "UdpLayer::readPkt() from : " << from << std::endl;
|
||||
std::cerr << printPkt(inbuf, nsize);
|
||||
#endif
|
||||
// send to reciever.
|
||||
recv -> recvPkt(inbuf, nsize, from);
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef DEBUG_UDP_LAYER
|
||||
std::cerr << "UdpLayer::readPkt() not ready" << from;
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int UdpLayer::sendPkt(void *data, int size, sockaddr_in &to, int ttl)
|
||||
{
|
||||
/* if ttl is different -> set it */
|
||||
if (ttl != getTTL())
|
||||
{
|
||||
setTTL(ttl);
|
||||
}
|
||||
|
||||
/* and send! */
|
||||
#ifdef DEBUG_UDP_LAYER
|
||||
std::cerr << "UdpLayer::sendPkt() to: " << to << std::endl;
|
||||
std::cerr << printPkt(data, size);
|
||||
#endif
|
||||
sendUdpPacket(data, size, to);
|
||||
return size;
|
||||
}
|
||||
|
||||
/* setup connections */
|
||||
int UdpLayer::openSocket()
|
||||
{
|
||||
sockMtx.lock(); /********** LOCK MUTEX *********/
|
||||
|
||||
/* make a socket */
|
||||
sockfd = tounet_socket(PF_INET, SOCK_DGRAM, 0);
|
||||
#ifdef DEBUG_UDP_LAYER
|
||||
std::cerr << "UpdStreamer::openSocket()" << std::endl;
|
||||
#endif
|
||||
/* bind to address */
|
||||
|
||||
|
||||
#ifdef OPEN_UNIVERSAL_PORT
|
||||
struct sockaddr_in tmpaddr = laddr;
|
||||
tmpaddr.sin_addr.s_addr = 0;
|
||||
if (0 != tounet_bind(sockfd, (struct sockaddr *) (&tmpaddr), sizeof(tmpaddr)))
|
||||
#else
|
||||
if (0 != tounet_bind(sockfd, (struct sockaddr *) (&laddr), sizeof(laddr)))
|
||||
#endif
|
||||
{
|
||||
#ifdef DEBUG_UDP_LAYER
|
||||
std::cerr << "Socket Failed to Bind to : " << laddr << std::endl;
|
||||
std::cerr << "Error: " << tounet_errno() << std::endl;
|
||||
#endif
|
||||
errorState = EADDRINUSE;
|
||||
//exit(1);
|
||||
|
||||
sockMtx.unlock(); /******** UNLOCK MUTEX *********/
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (-1 == tounet_fcntl(sockfd, F_SETFL, O_NONBLOCK))
|
||||
{
|
||||
#ifdef DEBUG_UDP_LAYER
|
||||
std::cerr << "Failed to Make Non-Blocking" << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
errorState = 0;
|
||||
|
||||
#ifdef DEBUG_UDP_LAYER
|
||||
std::cerr << "Socket Bound to : " << laddr << std::endl;
|
||||
#endif
|
||||
|
||||
sockMtx.unlock(); /******** UNLOCK MUTEX *********/
|
||||
|
||||
#ifdef DEBUG_UDP_LAYER
|
||||
std::cerr << "Setting TTL to " << UDP_DEF_TTL << std::endl;
|
||||
#endif
|
||||
setTTL(UDP_DEF_TTL);
|
||||
|
||||
// start up our thread.
|
||||
{
|
||||
RsStackMutex stack(sockMtx); /********** LOCK MUTEX *********/
|
||||
stopThread = false;
|
||||
}
|
||||
start();
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
int UdpLayer::setTTL(int t)
|
||||
{
|
||||
sockMtx.lock(); /********** LOCK MUTEX *********/
|
||||
|
||||
int err = tounet_setsockopt(sockfd, IPPROTO_IP, IP_TTL, &t, sizeof(int));
|
||||
ttl = t;
|
||||
|
||||
sockMtx.unlock(); /******** UNLOCK MUTEX *********/
|
||||
|
||||
#ifdef DEBUG_UDP_LAYER
|
||||
std::cerr << "UdpLayer::setTTL(" << t << ") returned: " << err;
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int UdpLayer::getTTL()
|
||||
{
|
||||
sockMtx.lock(); /********** LOCK MUTEX *********/
|
||||
|
||||
int t = ttl;
|
||||
|
||||
sockMtx.unlock(); /******** UNLOCK MUTEX *********/
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
/* monitoring / updates */
|
||||
int UdpLayer::okay()
|
||||
{
|
||||
sockMtx.lock(); /********** LOCK MUTEX *********/
|
||||
|
||||
bool nonFatalError = ((errorState == 0) ||
|
||||
(errorState == EAGAIN) ||
|
||||
(errorState == EINPROGRESS));
|
||||
|
||||
sockMtx.unlock(); /******** UNLOCK MUTEX *********/
|
||||
|
||||
#ifdef DEBUG_UDP_LAYER
|
||||
if (!nonFatalError)
|
||||
{
|
||||
std::cerr << "UdpLayer::NOT okay(): Error: " << errorState << std::endl;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return nonFatalError;
|
||||
}
|
||||
|
||||
int UdpLayer::tick()
|
||||
{
|
||||
#ifdef DEBUG_UDP_LAYER
|
||||
std::cerr << "UdpLayer::tick()" << std::endl;
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
/******************* Internals *************************************/
|
||||
|
||||
int UdpLayer::receiveUdpPacket(void *data, int *size, struct sockaddr_in &from)
|
||||
{
|
||||
struct sockaddr_in fromaddr;
|
||||
socklen_t fromsize = sizeof(fromaddr);
|
||||
int insize = *size;
|
||||
|
||||
sockMtx.lock(); /********** LOCK MUTEX *********/
|
||||
|
||||
insize = tounet_recvfrom(sockfd,data,insize,0,
|
||||
(struct sockaddr*)&fromaddr,&fromsize);
|
||||
|
||||
sockMtx.unlock(); /******** UNLOCK MUTEX *********/
|
||||
|
||||
if (0 < insize)
|
||||
{
|
||||
#ifdef DEBUG_UDP_LAYER
|
||||
std::cerr << "receiveUdpPacket() from: " << fromaddr;
|
||||
std::cerr << " Size: " << insize;
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
*size = insize;
|
||||
from = fromaddr;
|
||||
return insize;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int UdpLayer::sendUdpPacket(const void *data, int size, struct sockaddr_in &to)
|
||||
{
|
||||
/* send out */
|
||||
#ifdef DEBUG_UDP_LAYER
|
||||
std::cerr << "UdpLayer::sendUdpPacket(): size: " << size;
|
||||
std::cerr << " To: " << to << std::endl;
|
||||
#endif
|
||||
struct sockaddr_in toaddr = to;
|
||||
|
||||
sockMtx.lock(); /********** LOCK MUTEX *********/
|
||||
|
||||
tounet_sendto(sockfd, data, size, 0,
|
||||
(struct sockaddr *) &(toaddr),
|
||||
sizeof(toaddr));
|
||||
|
||||
sockMtx.unlock(); /******** UNLOCK MUTEX *********/
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,187 +0,0 @@
|
|||
/*
|
||||
* "$Id: udplayer.h,v 1.5 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".
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef TOU_UDP_LAYER_H
|
||||
#define TOU_UDP_LAYER_H
|
||||
|
||||
|
||||
/*
|
||||
#include <netinet/in.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
*/
|
||||
|
||||
|
||||
#include "util/rsthreads.h"
|
||||
|
||||
/* universal networking functions */
|
||||
#include "tou_net.h"
|
||||
|
||||
#include <iosfwd>
|
||||
#include <list>
|
||||
#include <deque>
|
||||
|
||||
bool operator==(const struct sockaddr_in &addr, const struct sockaddr_in &addr2);
|
||||
bool operator<(const struct sockaddr_in &addr, const struct sockaddr_in &addr2);
|
||||
|
||||
std::string printPkt(void *d, int size);
|
||||
std::string printPktOffset(unsigned int offset, void *d, unsigned int size);
|
||||
|
||||
|
||||
/* UdpLayer ..... is the bottom layer which
|
||||
* just sends and receives Udp packets.
|
||||
*/
|
||||
|
||||
class UdpReceiver
|
||||
{
|
||||
public:
|
||||
virtual void recvPkt(void *data, int size, struct sockaddr_in &from) = 0;
|
||||
};
|
||||
|
||||
class UdpLayer: public RsThread
|
||||
{
|
||||
public:
|
||||
|
||||
UdpLayer(UdpReceiver *recv, struct sockaddr_in &local);
|
||||
virtual ~UdpLayer() { return; }
|
||||
|
||||
int reset(struct sockaddr_in &local); /* calls join, close, openSocket */
|
||||
|
||||
int status(std::ostream &out);
|
||||
|
||||
/* setup connections */
|
||||
int close();
|
||||
int openSocket();
|
||||
|
||||
/* RsThread functions */
|
||||
virtual void run(); /* called once the thread is started */
|
||||
|
||||
void recv_loop(); /* uses callback to UdpReceiver */
|
||||
|
||||
/* Higher Level Interface */
|
||||
//int readPkt(void *data, int *size, struct sockaddr_in &from);
|
||||
int sendPkt(void *data, int size, struct sockaddr_in &to, int ttl);
|
||||
|
||||
/* monitoring / updates */
|
||||
int okay();
|
||||
int tick();
|
||||
|
||||
|
||||
/* data */
|
||||
/* internals */
|
||||
protected:
|
||||
|
||||
virtual int receiveUdpPacket(void *data, int *size, struct sockaddr_in &from);
|
||||
virtual int sendUdpPacket(const void *data, int size, struct sockaddr_in &to);
|
||||
|
||||
int setTTL(int t);
|
||||
int getTTL();
|
||||
|
||||
/* low level */
|
||||
private:
|
||||
|
||||
UdpReceiver *recv;
|
||||
|
||||
struct sockaddr_in laddr; /* local addr */
|
||||
|
||||
int errorState;
|
||||
int sockfd;
|
||||
int ttl;
|
||||
bool stopThread;
|
||||
|
||||
RsMutex sockMtx;
|
||||
};
|
||||
|
||||
#include <iostream>
|
||||
#include <stdlib.h>
|
||||
|
||||
class LossyUdpLayer: public UdpLayer
|
||||
{
|
||||
public:
|
||||
|
||||
LossyUdpLayer(UdpReceiver *udpr, struct sockaddr_in &local, double frac)
|
||||
:UdpLayer(udpr, local), lossFraction(frac)
|
||||
{
|
||||
return;
|
||||
}
|
||||
virtual ~LossyUdpLayer() { return; }
|
||||
|
||||
protected:
|
||||
|
||||
virtual int receiveUdpPacket(void *data, int *size, struct sockaddr_in &from)
|
||||
{
|
||||
double prob = (1.0 * (rand() / (RAND_MAX + 1.0)));
|
||||
|
||||
if (prob < lossFraction)
|
||||
{
|
||||
/* but discard */
|
||||
if (0 < UdpLayer::receiveUdpPacket(data, size, from))
|
||||
{
|
||||
std::cerr << "LossyUdpLayer::receiveUdpPacket() Dropping packet!";
|
||||
std::cerr << std::endl;
|
||||
std::cerr << printPkt(data, *size);
|
||||
std::cerr << std::endl;
|
||||
std::cerr << "LossyUdpLayer::receiveUdpPacket() Packet Dropped!";
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
|
||||
size = 0;
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
||||
// otherwise read normally;
|
||||
return UdpLayer::receiveUdpPacket(data, size, from);
|
||||
}
|
||||
|
||||
|
||||
virtual int sendUdpPacket(const void *data, int size, struct sockaddr_in &to)
|
||||
{
|
||||
double prob = (1.0 * (rand() / (RAND_MAX + 1.0)));
|
||||
|
||||
if (prob < lossFraction)
|
||||
{
|
||||
/* discard */
|
||||
|
||||
std::cerr << "LossyUdpLayer::sendUdpPacket() Dropping packet!";
|
||||
std::cerr << std::endl;
|
||||
std::cerr << printPkt((void *) data, size);
|
||||
std::cerr << std::endl;
|
||||
std::cerr << "LossyUdpLayer::sendUdpPacket() Packet Dropped!";
|
||||
std::cerr << std::endl;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
// otherwise read normally;
|
||||
return UdpLayer::sendUdpPacket(data, size, to);
|
||||
}
|
||||
|
||||
double lossFraction;
|
||||
};
|
||||
|
||||
#endif
|
144
libretroshare/src/tcponudp/udppeer.cc
Normal file
144
libretroshare/src/tcponudp/udppeer.cc
Normal file
|
@ -0,0 +1,144 @@
|
|||
/*
|
||||
* tcponudp/udppeer.cc
|
||||
*
|
||||
* libretroshare.
|
||||
*
|
||||
* Copyright 2010 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 3 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 "udppeer.h"
|
||||
#include <iostream>
|
||||
|
||||
/*
|
||||
* #define DEBUG_UDP_PEER 1
|
||||
*/
|
||||
|
||||
|
||||
UdpPeerReceiver::UdpPeerReceiver(UdpPublisher *pub)
|
||||
:UdpSubReceiver(pub)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* higher level interface */
|
||||
int UdpPeerReceiver::recvPkt(void *data, int size, struct sockaddr_in &from)
|
||||
{
|
||||
/* print packet information */
|
||||
#ifdef DEBUG_UDP_PEER
|
||||
std::cerr << "UdpPeerReceiver::recvPkt(" << size << ") from: " << from;
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
RsStackMutex stack(peerMtx); /********** LOCK MUTEX *********/
|
||||
|
||||
/* look for a peer */
|
||||
std::map<struct sockaddr_in, UdpPeer *>::iterator it;
|
||||
it = streams.find(from);
|
||||
|
||||
if (it == streams.end())
|
||||
{
|
||||
/* peer unknown */
|
||||
#ifdef DEBUG_UDP_PEER
|
||||
std::cerr << "UdpPeerReceiver::recvPkt() Peer Unknown!";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* forward to them */
|
||||
#ifdef DEBUG_UDP_PEER
|
||||
std::cerr << "UdpPeerReceiver::recvPkt() Sending to UdpPeer: ";
|
||||
std::cerr << it->first;
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
(it->second)->recvPkt(data, size);
|
||||
return 1;
|
||||
}
|
||||
/* done */
|
||||
}
|
||||
|
||||
|
||||
int UdpPeerReceiver::status(std::ostream &out)
|
||||
{
|
||||
RsStackMutex stack(peerMtx); /********** LOCK MUTEX *********/
|
||||
|
||||
out << "UdpPeerReceiver::status()" << std::endl;
|
||||
out << "UdpPeerReceiver::peers:" << std::endl;
|
||||
std::map<struct sockaddr_in, UdpPeer *>::iterator it;
|
||||
for(it = streams.begin(); it != streams.end(); it++)
|
||||
{
|
||||
out << "\t" << it->first << std::endl;
|
||||
}
|
||||
out << std::endl;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* add a TCPonUDP stream */
|
||||
int UdpPeerReceiver::addUdpPeer(UdpPeer *peer, const struct sockaddr_in &raddr)
|
||||
{
|
||||
RsStackMutex stack(peerMtx); /********** LOCK MUTEX *********/
|
||||
|
||||
|
||||
/* check for duplicate */
|
||||
std::map<struct sockaddr_in, UdpPeer *>::iterator it;
|
||||
it = streams.find(raddr);
|
||||
bool ok = (it == streams.end());
|
||||
if (!ok)
|
||||
{
|
||||
#ifdef DEBUG_UDP_PEER
|
||||
std::cerr << "UdpPeerReceiver::addUdpPeer() Peer already exists!" << std::endl;
|
||||
std::cerr << "UdpPeerReceiver::addUdpPeer() ERROR" << std::endl;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
streams[raddr] = peer;
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
int UdpPeerReceiver::removeUdpPeer(UdpPeer *peer)
|
||||
{
|
||||
RsStackMutex stack(peerMtx); /********** LOCK MUTEX *********/
|
||||
|
||||
/* check for duplicate */
|
||||
std::map<struct sockaddr_in, UdpPeer *>::iterator it;
|
||||
for(it = streams.begin(); it != streams.end(); it++)
|
||||
{
|
||||
if (it->second == peer)
|
||||
{
|
||||
#ifdef DEBUG_UDP_PEER
|
||||
std::cerr << "UdpPeerReceiver::removeUdpPeer() SUCCESS" << std::endl;
|
||||
#endif
|
||||
streams.erase(it);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG_UDP_PEER
|
||||
std::cerr << "UdpPeerReceiver::removeUdpPeer() ERROR" << std::endl;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
71
libretroshare/src/tcponudp/udppeer.h
Normal file
71
libretroshare/src/tcponudp/udppeer.h
Normal file
|
@ -0,0 +1,71 @@
|
|||
#ifndef RS_UDP_PEER_RECV_H
|
||||
#define RS_UDP_PEER_RECV_H
|
||||
|
||||
/*
|
||||
* tcponudp/udppeer.h
|
||||
*
|
||||
* libretroshare.
|
||||
*
|
||||
* Copyright 2010 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 3 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 <netinet/in.h>
|
||||
|
||||
#include "util/rsthreads.h"
|
||||
|
||||
#include <iosfwd>
|
||||
#include <list>
|
||||
#include <deque>
|
||||
|
||||
#include "tcponudp/rsudpstack.h"
|
||||
|
||||
class UdpPeer
|
||||
{
|
||||
public:
|
||||
virtual ~UdpPeer() { return; }
|
||||
virtual void recvPkt(void *data, int size) = 0;
|
||||
};
|
||||
|
||||
|
||||
class UdpPeerReceiver: public UdpSubReceiver
|
||||
{
|
||||
public:
|
||||
|
||||
UdpPeerReceiver(UdpPublisher *pub);
|
||||
virtual ~UdpPeerReceiver() { return; }
|
||||
|
||||
/* add a TCPonUDP stream */
|
||||
int addUdpPeer(UdpPeer *peer, const struct sockaddr_in &raddr);
|
||||
int removeUdpPeer(UdpPeer *peer);
|
||||
|
||||
/* callback for recved data (overloaded from UdpReceiver) */
|
||||
virtual int recvPkt(void *data, int size, struct sockaddr_in &from);
|
||||
|
||||
int status(std::ostream &out);
|
||||
|
||||
private:
|
||||
|
||||
RsMutex peerMtx; /* for all class data (below) */
|
||||
|
||||
std::map<struct sockaddr_in, UdpPeer *> streams;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,91 +0,0 @@
|
|||
/*
|
||||
* libretroshare/src/tcponudp: udpsock_test.cc
|
||||
*
|
||||
* TCP-on-UDP (tou) network interface for RetroShare.
|
||||
*
|
||||
* Copyright 2007-2008 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 "udptestfn.h"
|
||||
#include "udplayer.h"
|
||||
|
||||
#define MAX_PEERS 16
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
/* get local and remote addresses */
|
||||
struct sockaddr_in local;
|
||||
struct sockaddr_in peers[MAX_PEERS];
|
||||
int numpeers = 0;
|
||||
int i,j;
|
||||
|
||||
local.sin_family = AF_INET;
|
||||
inet_aton("127.0.0.1", &(local.sin_addr));
|
||||
local.sin_port = htons(8767);
|
||||
|
||||
for(i = 0; i < MAX_PEERS; i++)
|
||||
{
|
||||
peers[i].sin_family = AF_INET;
|
||||
inet_aton("127.0.0.1", &(peers[i].sin_addr));
|
||||
peers[i].sin_port = htons(8768);
|
||||
}
|
||||
|
||||
if (argc < 3)
|
||||
{
|
||||
std::cerr << "Usage: " << argv[0] << " <l-port> [<p-port1 ..]";
|
||||
std::cerr << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
local.sin_port = htons(atoi(argv[1]));
|
||||
std::cerr << argv[0] << " Local Port: " << ntohs(local.sin_port);
|
||||
std::cerr << std::endl;
|
||||
for(i = 2; i < argc; i++)
|
||||
{
|
||||
numpeers++;
|
||||
peers[i-2].sin_port = htons(atoi(argv[i]));
|
||||
std::cerr << "\tPeer Port: " << ntohs(peers[i-2].sin_port);
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
|
||||
/* create a udp layer */
|
||||
UdpRecvTest recv;
|
||||
UdpLayer udpl(&recv, local);
|
||||
|
||||
udpl.start();
|
||||
|
||||
int size = 12;
|
||||
void *data = malloc(size);
|
||||
int ttl = 64;
|
||||
|
||||
/* push packets to the peer */
|
||||
for(i = 0; i < 60; i++)
|
||||
{
|
||||
sleep(1);
|
||||
for(j = 0; j < numpeers; j++)
|
||||
{
|
||||
udpl.sendPkt(data, size, peers[j], ttl);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1,91 +0,0 @@
|
|||
/*
|
||||
* libretroshare/src/tcponudp: udpsort_test.cc
|
||||
*
|
||||
* TCP-on-UDP (tou) network interface for RetroShare.
|
||||
*
|
||||
* Copyright 2007-2008 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 "udptestfn.h"
|
||||
#include "udpsorter.h"
|
||||
|
||||
#define MAX_PEERS 16
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
/* get local and remote addresses */
|
||||
struct sockaddr_in local;
|
||||
struct sockaddr_in peers[MAX_PEERS];
|
||||
int numpeers = 0;
|
||||
int i,j;
|
||||
|
||||
local.sin_family = AF_INET;
|
||||
inet_aton("127.0.0.1", &(local.sin_addr));
|
||||
local.sin_port = htons(8767);
|
||||
|
||||
for(i = 0; i < MAX_PEERS; i++)
|
||||
{
|
||||
peers[i].sin_family = AF_INET;
|
||||
inet_aton("127.0.0.1", &(peers[i].sin_addr));
|
||||
peers[i].sin_port = htons(8768);
|
||||
}
|
||||
|
||||
if (argc < 3)
|
||||
{
|
||||
std::cerr << "Usage: " << argv[0] << " <l-port> [<p-port1 ..]";
|
||||
std::cerr << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
local.sin_port = htons(atoi(argv[1]));
|
||||
std::cerr << argv[0] << " Local Port: " << ntohs(local.sin_port);
|
||||
std::cerr << std::endl;
|
||||
|
||||
UdpSorter udps(local);
|
||||
|
||||
for(i = 2; i < argc; i++)
|
||||
{
|
||||
numpeers++;
|
||||
peers[i-2].sin_port = htons(atoi(argv[i]));
|
||||
std::cerr << "\tPeer Port: " << ntohs(peers[i-2].sin_port);
|
||||
std::cerr << std::endl;
|
||||
|
||||
UdpPeerTest *pt = new UdpPeerTest(peers[i-2]);
|
||||
udps.addUdpPeer(pt, peers[i-2]);
|
||||
}
|
||||
|
||||
int size = 12;
|
||||
void *data = malloc(size);
|
||||
int ttl = 64;
|
||||
|
||||
/* push packets to the peer */
|
||||
for(i = 0; i < 60; i++)
|
||||
{
|
||||
sleep(1);
|
||||
for(j = 0; j < numpeers; j++)
|
||||
{
|
||||
udps.sendPkt(data, size, peers[j], ttl);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1,13 +1,13 @@
|
|||
/*
|
||||
* libretroshare/src/tcponudp: udpsorter.cc
|
||||
* tcponudp/udpstunner.cc
|
||||
*
|
||||
* TCP-on-UDP (tou) network interface for RetroShare.
|
||||
* libretroshare.
|
||||
*
|
||||
* Copyright 2007-2008 by Robert Fernie.
|
||||
* Copyright 2010 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.
|
||||
* License Version 3 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
|
||||
|
@ -23,246 +23,97 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include "udpsorter.h"
|
||||
#include "util/rsnet.h"
|
||||
#include "util/rsprint.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "udpstunner.h"
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
#include "util/rsdebug.h"
|
||||
const int rsudpsorterzone = 28477;
|
||||
|
||||
static const int STUN_TTL = 64;
|
||||
|
||||
#define TOU_STUN_MIN_PEERS 5
|
||||
|
||||
/*
|
||||
* #define DEBUG_UDP_SORTER 1
|
||||
* #define DEBUG_UDP_STUN 1
|
||||
*/
|
||||
|
||||
|
||||
const int32_t TOU_STUN_MAX_FAIL_COUNT = 3; /* 3 tries (could be higher?) */
|
||||
const int32_t TOU_STUN_MAX_SEND_RATE = 5; /* every 5 seconds */
|
||||
const int32_t TOU_STUN_MAX_RECV_RATE = 25; /* every 25 seconds */
|
||||
const int32_t TOU_STUN_ADDR_MAX_AGE = 120; /* 2 minutes */
|
||||
|
||||
|
||||
|
||||
UdpSorter::UdpSorter(struct sockaddr_in &local)
|
||||
:udpLayer(NULL), laddr(local), eaddrKnown(false), eaddrStable(false),
|
||||
UdpStunner::UdpStunner(UdpPublisher *pub)
|
||||
:UdpSubReceiver(pub), eaddrKnown(false), eaddrStable(false),
|
||||
mStunKeepAlive(false), mStunLastRecv(0), mStunLastSend(0)
|
||||
|
||||
|
||||
{
|
||||
sockaddr_clear(&eaddr);
|
||||
|
||||
openSocket();
|
||||
return;
|
||||
}
|
||||
|
||||
bool UdpSorter::resetAddress(struct sockaddr_in &local)
|
||||
{
|
||||
return udpLayer->reset(local);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* higher level interface */
|
||||
void UdpSorter::recvPkt(void *data, int size, struct sockaddr_in &from)
|
||||
int UdpStunner::recvPkt(void *data, int size, struct sockaddr_in &from)
|
||||
{
|
||||
/* print packet information */
|
||||
#ifdef DEBUG_UDP_SORTER
|
||||
std::cerr << "UdpSorter::recvPkt(" << size << ") from: " << from;
|
||||
#ifdef DEBUG_UDP_STUNNER
|
||||
std::cerr << "UdpStunner::recvPkt(" << size << ") from: " << from;
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
sortMtx.lock(); /********** LOCK MUTEX *********/
|
||||
mStunLastRecv = time(NULL);
|
||||
|
||||
/* look for a peer */
|
||||
std::map<struct sockaddr_in, UdpPeer *>::iterator it;
|
||||
it = streams.find(from);
|
||||
RsStackMutex stack(stunMtx); /********** LOCK MUTEX *********/
|
||||
|
||||
/* check for STUN packet */
|
||||
if (UdpStun_isStunPacket(data, size))
|
||||
{
|
||||
#ifdef DEBUG_UDP_SORTER
|
||||
std::cerr << "UdpSorter::recvPkt() is Stun Packet";
|
||||
mStunLastRecv = time(NULL);
|
||||
#ifdef DEBUG_UDP_STUNNER
|
||||
std::cerr << "UdpStunner::recvPkt() is Stun Packet";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
/* respond */
|
||||
locked_handleStunPkt(data, size, from);
|
||||
}
|
||||
else if (it == streams.end())
|
||||
{
|
||||
/* peer unknown */
|
||||
#ifdef DEBUG_UDP_SORTER
|
||||
std::cerr << "UdpSorter::recvPkt() Peer Unknown!";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
std::ostringstream out;
|
||||
out << "UdpSorter::recvPkt() ";
|
||||
out << "from unknown: " << from;
|
||||
rslog(RSL_WARNING,rsudpsorterzone,out.str());
|
||||
}
|
||||
else
|
||||
{
|
||||
/* forward to them */
|
||||
#ifdef DEBUG_UDP_SORTER
|
||||
std::cerr << "UdpSorter::recvPkt() Sending to UdpPeer: ";
|
||||
std::cerr << it->first;
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
(it->second)->recvPkt(data, size);
|
||||
}
|
||||
|
||||
sortMtx.unlock(); /******** UNLOCK MUTEX *********/
|
||||
/* done */
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int UdpSorter::sendPkt(void *data, int size, struct sockaddr_in &to, int ttl)
|
||||
int UdpStunner::status(std::ostream &out)
|
||||
{
|
||||
/* print packet information */
|
||||
#ifdef DEBUG_UDP_SORTER
|
||||
std::cerr << "UdpSorter::sendPkt(" << size << ") ttl: " << ttl;
|
||||
std::cerr << " to: " << to;
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
RsStackMutex stack(stunMtx); /********** LOCK MUTEX *********/
|
||||
|
||||
/* send to udpLayer */
|
||||
return udpLayer->sendPkt(data, size, to, ttl);
|
||||
}
|
||||
|
||||
int UdpSorter::status(std::ostream &out)
|
||||
{
|
||||
sortMtx.lock(); /********** LOCK MUTEX *********/
|
||||
|
||||
out << "UdpSorter::status()" << std::endl;
|
||||
out << "localaddr: " << laddr << std::endl;
|
||||
out << "UdpSorter::peers:" << std::endl;
|
||||
std::map<struct sockaddr_in, UdpPeer *>::iterator it;
|
||||
for(it = streams.begin(); it != streams.end(); it++)
|
||||
out << "UdpStunner::status()" << std::endl;
|
||||
out << "UdpStunner::potentialpeers:" << std::endl;
|
||||
std::list<TouStunPeer>::iterator it;
|
||||
for(it = mStunList.begin(); it != mStunList.end(); it++)
|
||||
{
|
||||
out << "\t" << it->first << std::endl;
|
||||
out << "\t" << it->id << std::endl;
|
||||
}
|
||||
out << std::endl;
|
||||
|
||||
sortMtx.unlock(); /******** UNLOCK MUTEX *********/
|
||||
|
||||
udpLayer->status(out);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* setup connections */
|
||||
int UdpSorter::openSocket()
|
||||
int UdpStunner::tick()
|
||||
{
|
||||
udpLayer = new UdpLayer(this, laddr);
|
||||
// start is called by udpLayer now, for consistency
|
||||
// with reset!
|
||||
//udpLayer->start();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* monitoring / updates */
|
||||
int UdpSorter::okay()
|
||||
{
|
||||
return udpLayer->okay();
|
||||
}
|
||||
|
||||
int UdpSorter::tick()
|
||||
{
|
||||
#ifdef DEBUG_UDP_SORTER
|
||||
std::cerr << "UdpSorter::tick()" << std::endl;
|
||||
#ifdef DEBUG_UDP_STUNNER
|
||||
std::cerr << "UdpStunner::tick()" << std::endl;
|
||||
#endif
|
||||
checkStunKeepAlive();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int UdpSorter::close()
|
||||
{
|
||||
/* TODO */
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* add a TCPonUDP stream */
|
||||
int UdpSorter::addUdpPeer(UdpPeer *peer, const struct sockaddr_in &raddr)
|
||||
{
|
||||
sortMtx.lock(); /********** LOCK MUTEX *********/
|
||||
|
||||
|
||||
/* check for duplicate */
|
||||
std::map<struct sockaddr_in, UdpPeer *>::iterator it;
|
||||
it = streams.find(raddr);
|
||||
bool ok = (it == streams.end());
|
||||
if (!ok)
|
||||
{
|
||||
#ifdef DEBUG_UDP_SORTER
|
||||
std::cerr << "UdpSorter::addUdpPeer() Peer already exists!" << std::endl;
|
||||
std::cerr << "UdpSorter::addUdpPeer() ERROR" << std::endl;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
streams[raddr] = peer;
|
||||
}
|
||||
|
||||
sortMtx.unlock(); /******** UNLOCK MUTEX *********/
|
||||
return ok;
|
||||
}
|
||||
|
||||
int UdpSorter::removeUdpPeer(UdpPeer *peer)
|
||||
{
|
||||
RsStackMutex stack(sortMtx); /********** LOCK MUTEX *********/
|
||||
|
||||
/* check for duplicate */
|
||||
std::map<struct sockaddr_in, UdpPeer *>::iterator it;
|
||||
for(it = streams.begin(); it != streams.end(); it++)
|
||||
{
|
||||
if (it->second == peer)
|
||||
{
|
||||
#ifdef DEBUG_UDP_SORTER
|
||||
std::cerr << "UdpSorter::removeUdpPeer() SUCCESS" << std::endl;
|
||||
#endif
|
||||
streams.erase(it);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG_UDP_SORTER
|
||||
std::cerr << "UdpSorter::removeUdpPeer() ERROR" << std::endl;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/******************************* STUN Handling ********************************/
|
||||
|
||||
/* respond */
|
||||
bool UdpSorter::locked_handleStunPkt(void *data, int size, struct sockaddr_in &from)
|
||||
bool UdpStunner::locked_handleStunPkt(void *data, int size, struct sockaddr_in &from)
|
||||
{
|
||||
if (size == 20) /* request */
|
||||
{
|
||||
#ifdef DEBUG_UDP_SORTER
|
||||
std::cerr << "UdpSorter::handleStunPkt() got Request from: ";
|
||||
std::cerr << rs_inet_ntoa(from.sin_addr) << ":" << ntohs(from.sin_port);
|
||||
#ifdef DEBUG_UDP_STUNNER
|
||||
std::cerr << "UdpStunner::handleStunPkt() got Request from: ";
|
||||
std::cerr << inet_ntoa(from.sin_addr) << ":" << ntohs(from.sin_port);
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
{
|
||||
std::ostringstream out;
|
||||
out << "UdpSorter::handleStunPkt() got Request from: " << from;
|
||||
rslog(RSL_WARNING,rsudpsorterzone,out.str());
|
||||
}
|
||||
|
||||
/* generate a response */
|
||||
int len;
|
||||
void *pkt = UdpStun_generate_stun_reply(&from, &len);
|
||||
|
@ -272,8 +123,8 @@ bool UdpSorter::locked_handleStunPkt(void *data, int size, struct sockaddr_in &f
|
|||
int sentlen = sendPkt(pkt, len, from, STUN_TTL);
|
||||
free(pkt);
|
||||
|
||||
#ifdef DEBUG_UDP_SORTER
|
||||
std::cerr << "UdpSorter::handleStunPkt() sent Response size:" << sentlen;
|
||||
#ifdef DEBUG_UDP_STUNNER
|
||||
std::cerr << "UdpStunner::handleStunPkt() sent Response size:" << sentlen;
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
|
@ -281,8 +132,8 @@ bool UdpSorter::locked_handleStunPkt(void *data, int size, struct sockaddr_in &f
|
|||
}
|
||||
else if (size == 28)
|
||||
{
|
||||
#ifdef DEBUG_UDP_SORTER
|
||||
std::cerr << "UdpSorter::handleStunPkt() got Response";
|
||||
#ifdef DEBUG_UDP_STUNNER
|
||||
std::cerr << "UdpStunner::handleStunPkt() got Response";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
/* got response */
|
||||
|
@ -290,42 +141,36 @@ bool UdpSorter::locked_handleStunPkt(void *data, int size, struct sockaddr_in &f
|
|||
bool good = UdpStun_response(data, size, eAddr);
|
||||
if (good)
|
||||
{
|
||||
#ifdef DEBUG_UDP_SORTER
|
||||
std::cerr << "UdpSorter::handleStunPkt() got Ext Addr: ";
|
||||
std::cerr << rs_inet_ntoa(eAddr.sin_addr) << ":" << ntohs(eAddr.sin_port);
|
||||
#ifdef DEBUG_UDP_STUNNER
|
||||
std::cerr << "UdpStunner::handleStunPkt() got Ext Addr: ";
|
||||
std::cerr << inet_ntoa(eAddr.sin_addr) << ":" << ntohs(eAddr.sin_port);
|
||||
out << " from: " << from;
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
{
|
||||
std::ostringstream out;
|
||||
out << "UdpSorter::handleStunPkt() got Response from: " << from;
|
||||
out << " Ext Addr: " << eAddr;
|
||||
rslog(RSL_WARNING,rsudpsorterzone,out.str());
|
||||
}
|
||||
|
||||
locked_recvdStun(from, eAddr);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG_UDP_SORTER
|
||||
std::cerr << "UdpSorter::handleStunPkt() Bad Packet";
|
||||
#ifdef DEBUG_UDP_STUNNER
|
||||
std::cerr << "UdpStunner::handleStunPkt() Bad Packet";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool UdpSorter::externalAddr(struct sockaddr_in &external, uint8_t &stable)
|
||||
bool UdpStunner::externalAddr(struct sockaddr_in &external, uint8_t &stable)
|
||||
{
|
||||
RsStackMutex stack(sortMtx); /********** LOCK MUTEX *********/
|
||||
RsStackMutex stack(stunMtx); /********** LOCK MUTEX *********/
|
||||
|
||||
if (eaddrKnown)
|
||||
{
|
||||
/* address timeout */
|
||||
if (time(NULL) - eaddrTime > TOU_STUN_ADDR_MAX_AGE)
|
||||
{
|
||||
std::cerr << "UdpSorter::externalAddr() eaddr expired";
|
||||
std::cerr << "UdpStunner::externalAddr() eaddr expired";
|
||||
std::cerr << std::endl;
|
||||
|
||||
return false;
|
||||
|
@ -338,16 +183,16 @@ bool UdpSorter::externalAddr(struct sockaddr_in &external, uint8_t &stable)
|
|||
else
|
||||
stable = 0;
|
||||
|
||||
#ifdef DEBUG_UDP_SORTER
|
||||
std::cerr << "UdpSorter::externalAddr() eaddr:" << rs_inet_ntoa(external.sin_addr);
|
||||
#ifdef DEBUG_UDP_STUNNER
|
||||
std::cerr << "UdpStunner::externalAddr() eaddr:" << inet_ntoa(external.sin_addr);
|
||||
std::cerr << ":" << ntohs(external.sin_port) << " stable: " << (int) stable;
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
#ifdef DEBUG_UDP_SORTER
|
||||
std::cerr << "UdpSorter::externalAddr() eaddr unknown";
|
||||
#ifdef DEBUG_UDP_STUNNER
|
||||
std::cerr << "UdpStunner::externalAddr() eaddr unknown";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
|
@ -355,21 +200,14 @@ bool UdpSorter::externalAddr(struct sockaddr_in &external, uint8_t &stable)
|
|||
}
|
||||
|
||||
|
||||
int UdpSorter::doStun(struct sockaddr_in stun_addr)
|
||||
int UdpStunner::doStun(struct sockaddr_in stun_addr)
|
||||
{
|
||||
#ifdef DEBUG_UDP_SORTER
|
||||
std::cerr << "UdpSorter::doStun()";
|
||||
#ifdef DEBUG_UDP_STUNNER
|
||||
std::cerr << "UdpStunner::doStun()";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
/* send out a stun packet -> save in the local variable */
|
||||
if (!okay())
|
||||
{
|
||||
#ifdef DEBUG_UDP_SORTER
|
||||
std::cerr << "UdpSorter::doStun() Not Active";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
#define MAX_STUN_SIZE 64
|
||||
char stundata[MAX_STUN_SIZE];
|
||||
|
@ -377,8 +215,8 @@ int UdpSorter::doStun(struct sockaddr_in stun_addr)
|
|||
bool done = UdpStun_generate_stun_pkt(stundata, &tmplen);
|
||||
if (!done)
|
||||
{
|
||||
#ifdef DEBUG_UDP_SORTER
|
||||
std::cerr << "UdpSorter::doStun() Failed";
|
||||
#ifdef DEBUG_UDP_STUNNER
|
||||
std::cerr << "UdpStunner::doStun() Failed";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
//pqioutput(PQL_ALERT, pqistunzone, "pqistunner::stun() Failed!");
|
||||
|
@ -388,16 +226,17 @@ int UdpSorter::doStun(struct sockaddr_in stun_addr)
|
|||
/* send it off */
|
||||
int sentlen = sendPkt(stundata, tmplen, stun_addr, STUN_TTL);
|
||||
|
||||
sortMtx.lock(); /********** LOCK MUTEX *********/
|
||||
mStunLastSend = time(NULL);
|
||||
sortMtx.unlock(); /******** UNLOCK MUTEX *********/
|
||||
{
|
||||
RsStackMutex stack(stunMtx); /********** LOCK MUTEX *********/
|
||||
mStunLastSend = time(NULL);
|
||||
}
|
||||
|
||||
#ifdef DEBUG_UDP_SORTER
|
||||
#ifdef DEBUG_UDP_STUNNER
|
||||
std::ostringstream out;
|
||||
out << "UdpSorter::doStun() Sent Stun Packet(" << sentlen << ") from:";
|
||||
out << rs_inet_ntoa(laddr.sin_addr) << ":" << ntohs(laddr.sin_port);
|
||||
out << "UdpStunner::doStun() Sent Stun Packet(" << sentlen << ") from:";
|
||||
out << inet_ntoa(laddr.sin_addr) << ":" << ntohs(laddr.sin_port);
|
||||
out << " to:";
|
||||
out << rs_inet_ntoa(stun_addr.sin_addr) << ":" << ntohs(stun_addr.sin_port);
|
||||
out << inet_ntoa(stun_addr.sin_addr) << ":" << ntohs(stun_addr.sin_port);
|
||||
|
||||
std::cerr << out.str() << std::endl;
|
||||
|
||||
|
@ -433,10 +272,10 @@ bool UdpStun_response(void *stun_pkt, int size, struct sockaddr_in &addr)
|
|||
addr.sin_port = ((uint16_t *) stun_pkt)[11];
|
||||
|
||||
|
||||
#ifdef DEBUG_UDP_SORTER
|
||||
#ifdef DEBUG_UDP_STUNNER
|
||||
std::ostringstream out;
|
||||
out << "UdpSorter::response() Recvd a Stun Response, ext_addr: ";
|
||||
out << rs_inet_ntoa(addr.sin_addr) << ":" << ntohs(addr.sin_port);
|
||||
out << "UdpStunner::response() Recvd a Stun Response, ext_addr: ";
|
||||
out << inet_ntoa(addr.sin_addr) << ":" << ntohs(addr.sin_port);
|
||||
std::cerr << out.str() << std::endl;
|
||||
#endif
|
||||
|
||||
|
@ -492,15 +331,15 @@ void *UdpStun_generate_stun_reply(struct sockaddr_in *stun_addr, int *len)
|
|||
|
||||
bool UdpStun_isStunPacket(void *data, int size)
|
||||
{
|
||||
#ifdef DEBUG_UDP_SORTER
|
||||
std::cerr << "UdpSorter::isStunPacket() ?";
|
||||
#ifdef DEBUG_UDP_STUNNER
|
||||
std::cerr << "UdpStunner::isStunPacket() ?";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
if (size < 20)
|
||||
{
|
||||
#ifdef DEBUG_UDP_SORTER
|
||||
std::cerr << "UdpSorter::isStunPacket() (size < 20) -> false";
|
||||
#ifdef DEBUG_UDP_STUNNER
|
||||
std::cerr << "UdpStunner::isStunPacket() (size < 20) -> false";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
return false;
|
||||
|
@ -510,8 +349,8 @@ bool UdpStun_isStunPacket(void *data, int size)
|
|||
uint16_t pktsize = ntohs(((uint16_t *) data)[1]);
|
||||
if (size != pktsize)
|
||||
{
|
||||
#ifdef DEBUG_UDP_SORTER
|
||||
std::cerr << "UdpSorter::isStunPacket() (size != pktsize) -> false";
|
||||
#ifdef DEBUG_UDP_STUNNER
|
||||
std::cerr << "UdpStunner::isStunPacket() (size != pktsize) -> false";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
return false;
|
||||
|
@ -519,8 +358,8 @@ bool UdpStun_isStunPacket(void *data, int size)
|
|||
|
||||
if ((size == 20) && (0x0001 == ntohs(((uint16_t *) data)[0])))
|
||||
{
|
||||
#ifdef DEBUG_UDP_SORTER
|
||||
std::cerr << "UdpSorter::isStunPacket() (size=20 & data[0]=0x0001) -> true";
|
||||
#ifdef DEBUG_UDP_STUNNER
|
||||
std::cerr << "UdpStunner::isStunPacket() (size=20 & data[0]=0x0001) -> true";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
/* request */
|
||||
|
@ -529,8 +368,8 @@ bool UdpStun_isStunPacket(void *data, int size)
|
|||
|
||||
if ((size == 28) && (0x0101 == ntohs(((uint16_t *) data)[0])))
|
||||
{
|
||||
#ifdef DEBUG_UDP_SORTER
|
||||
std::cerr << "UdpSorter::isStunPacket() (size=28 & data[0]=0x0101) -> true";
|
||||
#ifdef DEBUG_UDP_STUNNER
|
||||
std::cerr << "UdpStunner::isStunPacket() (size=28 & data[0]=0x0101) -> true";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
/* response */
|
||||
|
@ -546,32 +385,33 @@ bool UdpStun_isStunPacket(void *data, int size)
|
|||
|
||||
/******************************* STUN Handling ********************************/
|
||||
|
||||
bool UdpSorter::setStunKeepAlive(uint32_t required)
|
||||
bool UdpStunner::setStunKeepAlive(uint32_t required)
|
||||
{
|
||||
sortMtx.lock(); /********** LOCK MUTEX *********/
|
||||
RsStackMutex stack(stunMtx); /********** LOCK MUTEX *********/
|
||||
|
||||
mStunKeepAlive = (required != 0);
|
||||
|
||||
#ifdef DEBUG_UDP_SORTER
|
||||
std::cerr << "UdpSorter::setStunKeepAlive() to: " << mStunKeepAlive;
|
||||
#ifdef DEBUG_UDP_STUNNER
|
||||
std::cerr << "UdpStunner::setStunKeepAlive() to: " << mStunKeepAlive;
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
sortMtx.unlock(); /******** UNLOCK MUTEX *********/
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool UdpSorter::addStunPeer(const struct sockaddr_in &remote, const char *peerid)
|
||||
bool UdpStunner::addStunPeer(const struct sockaddr_in &remote, const char *peerid)
|
||||
{
|
||||
/* add to the list */
|
||||
#ifdef DEBUG_UDP_SORTER
|
||||
std::cerr << "UdpSorter::addStunPeer()";
|
||||
#ifdef DEBUG_UDP_STUNNER
|
||||
std::cerr << "UdpStunner::addStunPeer()";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
sortMtx.lock(); /********** LOCK MUTEX *********/
|
||||
bool needStun = (!eaddrKnown);
|
||||
sortMtx.unlock(); /******** UNLOCK MUTEX *********/
|
||||
bool needStun;
|
||||
{
|
||||
RsStackMutex stack(stunMtx); /********** LOCK MUTEX *********/
|
||||
needStun = (!eaddrKnown);
|
||||
}
|
||||
|
||||
storeStunPeer(remote, peerid, needStun);
|
||||
|
||||
|
@ -584,15 +424,15 @@ bool UdpSorter::addStunPeer(const struct sockaddr_in &remote, const char *pee
|
|||
return true;
|
||||
}
|
||||
|
||||
bool UdpSorter::storeStunPeer(const struct sockaddr_in &remote, const char *peerid, bool sent)
|
||||
bool UdpStunner::storeStunPeer(const struct sockaddr_in &remote, const char *peerid, bool sent)
|
||||
{
|
||||
|
||||
#ifdef DEBUG_UDP_SORTER
|
||||
std::cerr << "UdpSorter::storeStunPeer()";
|
||||
#ifdef DEBUG_UDP_STUNNER
|
||||
std::cerr << "UdpStunner::storeStunPeer()";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
RsStackMutex stack(sortMtx); /********** LOCK MUTEX *********/
|
||||
RsStackMutex stack(stunMtx); /********** LOCK MUTEX *********/
|
||||
|
||||
std::list<TouStunPeer>::iterator it;
|
||||
for(it = mStunList.begin(); it != mStunList.end(); it++)
|
||||
|
@ -600,8 +440,8 @@ bool UdpSorter::storeStunPeer(const struct sockaddr_in &remote, const char *p
|
|||
if ((remote.sin_addr.s_addr == it->remote.sin_addr.s_addr) &&
|
||||
(remote.sin_port == it->remote.sin_port))
|
||||
{
|
||||
#ifdef DEBUG_UDP_SORTER
|
||||
std::cerr << "UdpSorter::storeStunPeer() Peer Already There!";
|
||||
#ifdef DEBUG_UDP_STUNNER
|
||||
std::cerr << "UdpStunner::storeStunPeer() Peer Already There!";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
/* already there */
|
||||
|
@ -623,8 +463,8 @@ bool UdpSorter::storeStunPeer(const struct sockaddr_in &remote, const char *p
|
|||
|
||||
mStunList.push_back(peer);
|
||||
|
||||
#ifdef DEBUG_UDP_SORTER
|
||||
std::cerr << "UdpSorter::storeStunPeer() Added Peer";
|
||||
#ifdef DEBUG_UDP_STUNNER
|
||||
std::cerr << "UdpStunner::storeStunPeer() Added Peer";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
|
@ -632,23 +472,23 @@ bool UdpSorter::storeStunPeer(const struct sockaddr_in &remote, const char *p
|
|||
}
|
||||
|
||||
|
||||
bool UdpSorter::checkStunKeepAlive()
|
||||
bool UdpStunner::checkStunKeepAlive()
|
||||
{
|
||||
|
||||
#ifdef DEBUG_UDP_SORTER
|
||||
std::cerr << "UdpSorter::checkStunKeepAlive()";
|
||||
#ifdef DEBUG_UDP_STUNNER
|
||||
std::cerr << "UdpStunner::checkStunKeepAlive()";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
TouStunPeer peer;
|
||||
time_t now;
|
||||
{
|
||||
RsStackMutex stack(sortMtx); /********** LOCK MUTEX *********/
|
||||
RsStackMutex stack(stunMtx); /********** LOCK MUTEX *********/
|
||||
|
||||
if (!mStunKeepAlive)
|
||||
{
|
||||
#ifdef DEBUG_UDP_SORTER
|
||||
std::cerr << "UdpSorter::checkStunKeepAlive() FALSE";
|
||||
#ifdef DEBUG_UDP_STUNNER
|
||||
std::cerr << "UdpStunner::checkStunKeepAlive() FALSE";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
return false; /* all good */
|
||||
|
@ -660,8 +500,8 @@ bool UdpSorter::checkStunKeepAlive()
|
|||
if ((now - mStunLastSend < TOU_STUN_MAX_SEND_RATE) ||
|
||||
(now - mStunLastRecv < TOU_STUN_MAX_RECV_RATE))
|
||||
{
|
||||
#ifdef DEBUG_UDP_SORTER
|
||||
std::cerr << "UdpSorter::checkStunKeepAlive() To Fast ... delaying";
|
||||
#ifdef DEBUG_UDP_STUNNER
|
||||
std::cerr << "UdpStunner::checkStunKeepAlive() To Fast ... delaying";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
/* too fast */
|
||||
|
@ -670,8 +510,8 @@ bool UdpSorter::checkStunKeepAlive()
|
|||
|
||||
if (mStunList.size() < 1)
|
||||
{
|
||||
#ifdef DEBUG_UDP_SORTER
|
||||
std::cerr << "UdpSorter::checkStunKeepAlive() No Peers in List!";
|
||||
#ifdef DEBUG_UDP_STUNNER
|
||||
std::cerr << "UdpStunner::checkStunKeepAlive() No Peers in List!";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
return false;
|
||||
|
@ -685,28 +525,28 @@ bool UdpSorter::checkStunKeepAlive()
|
|||
doStun(peer.remote);
|
||||
|
||||
{
|
||||
RsStackMutex stack(sortMtx); /********** LOCK MUTEX *********/
|
||||
RsStackMutex stack(stunMtx); /********** LOCK MUTEX *********/
|
||||
if (peer.failCount < TOU_STUN_MAX_FAIL_COUNT)
|
||||
{
|
||||
peer.failCount++;
|
||||
peer.lastsend = now;
|
||||
mStunList.push_back(peer);
|
||||
|
||||
#ifdef DEBUG_UDP_SORTER
|
||||
std::cerr << "UdpSorter::checkStunKeepAlive() pushing Stun peer to back of list";
|
||||
#ifdef DEBUG_UDP_STUNNER
|
||||
std::cerr << "UdpStunner::checkStunKeepAlive() pushing Stun peer to back of list";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef DEBUG_UDP_SORTER
|
||||
std::cerr << "UdpSorter::checkStunKeepAlive() Discarding bad stun peer";
|
||||
#ifdef DEBUG_UDP_STUNNER
|
||||
std::cerr << "UdpStunner::checkStunKeepAlive() Discarding bad stun peer";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef DEBUG_UDP_SORTER
|
||||
#ifdef DEBUG_UDP_STUNNER
|
||||
locked_printStunList();
|
||||
#endif
|
||||
|
||||
|
@ -717,14 +557,14 @@ bool UdpSorter::checkStunKeepAlive()
|
|||
}
|
||||
|
||||
|
||||
bool UdpSorter::locked_recvdStun(const struct sockaddr_in &remote, const struct sockaddr_in &extaddr)
|
||||
bool UdpStunner::locked_recvdStun(const struct sockaddr_in &remote, const struct sockaddr_in &extaddr)
|
||||
{
|
||||
#ifdef DEBUG_UDP_SORTER
|
||||
#ifdef DEBUG_UDP_STUNNER
|
||||
std::ostringstream out;
|
||||
out << "UdpSorter::locked_recvdStun() from:";
|
||||
out << rs_inet_ntoa(remote.sin_addr) << ":" << ntohs(remote.sin_port);
|
||||
out << "UdpStunner::locked_recvdStun() from:";
|
||||
out << inet_ntoa(remote.sin_addr) << ":" << ntohs(remote.sin_port);
|
||||
out << " claiming ExtAddr is:";
|
||||
out << rs_inet_ntoa(extaddr.sin_addr) << ":" << ntohs(extaddr.sin_port);
|
||||
out << inet_ntoa(extaddr.sin_addr) << ":" << ntohs(extaddr.sin_port);
|
||||
|
||||
std::cerr << out.str() << std::endl;
|
||||
#endif
|
||||
|
@ -745,7 +585,7 @@ bool UdpSorter::locked_recvdStun(const struct sockaddr_in &remote, const stru
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG_UDP_SORTER
|
||||
#ifdef DEBUG_UDP_STUNNER
|
||||
locked_printStunList();
|
||||
#endif
|
||||
|
||||
|
@ -754,11 +594,11 @@ bool UdpSorter::locked_recvdStun(const struct sockaddr_in &remote, const stru
|
|||
return found;
|
||||
}
|
||||
|
||||
bool UdpSorter::locked_checkExternalAddress()
|
||||
bool UdpStunner::locked_checkExternalAddress()
|
||||
{
|
||||
#ifdef DEBUG_UDP_SORTER
|
||||
#ifdef DEBUG_UDP_STUNNER
|
||||
std::ostringstream out;
|
||||
out << "UdpSorter::locked_checkExternalAddress()";
|
||||
out << "UdpStunner::locked_checkExternalAddress()";
|
||||
std::cerr << out.str() << std::endl;
|
||||
#endif
|
||||
|
||||
|
@ -811,8 +651,8 @@ bool UdpSorter::locked_checkExternalAddress()
|
|||
eaddr = p1->eaddr;
|
||||
eaddrTime = now;
|
||||
|
||||
#ifdef DEBUG_UDP_SORTER
|
||||
std::cerr << "UdpSorter::locked_checkExternalAddress() Found State:";
|
||||
#ifdef DEBUG_UDP_STUNNER
|
||||
std::cerr << "UdpStunner::locked_checkExternalAddress() Found State:";
|
||||
if (eaddrStable)
|
||||
std::cerr << " Stable NAT translation (GOOD!) ";
|
||||
else
|
||||
|
@ -828,9 +668,9 @@ bool UdpSorter::locked_checkExternalAddress()
|
|||
|
||||
|
||||
|
||||
bool UdpSorter::locked_printStunList()
|
||||
bool UdpStunner::locked_printStunList()
|
||||
{
|
||||
#ifdef DEBUG_UDP_SORTER
|
||||
#ifdef DEBUG_UDP_STUNNER
|
||||
std::ostringstream out;
|
||||
|
||||
time_t now = time(NULL);
|
||||
|
@ -841,9 +681,9 @@ bool UdpSorter::locked_printStunList()
|
|||
std::list<TouStunPeer>::iterator it;
|
||||
for(it = mStunList.begin(); it != mStunList.end(); it++)
|
||||
{
|
||||
out << "id:" << RsUtil::BinToHex(it->id) << " addr: " << rs_inet_ntoa(it->remote.sin_addr);
|
||||
out << "id:" << RsUtil::BinToHex(it->id) << " addr: " << inet_ntoa(it->remote.sin_addr);
|
||||
out << ":" << htons(it->remote.sin_port);
|
||||
out << " eaddr: " << rs_inet_ntoa(it->eaddr.sin_addr);
|
||||
out << " eaddr: " << inet_ntoa(it->eaddr.sin_addr);
|
||||
out << ":" << htons(it->eaddr.sin_port);
|
||||
out << " failCount: " << it->failCount;
|
||||
out << " lastSend: " << now - it->lastsend;
|
||||
|
@ -857,11 +697,11 @@ bool UdpSorter::locked_printStunList()
|
|||
}
|
||||
|
||||
|
||||
bool UdpSorter::getStunPeer(int idx, std::string &id,
|
||||
bool UdpStunner::getStunPeer(int idx, std::string &id,
|
||||
struct sockaddr_in &remote, struct sockaddr_in &eaddr,
|
||||
uint32_t &failCount, time_t &lastSend)
|
||||
{
|
||||
RsStackMutex stack(sortMtx); /********** LOCK MUTEX *********/
|
||||
RsStackMutex stack(stunMtx); /********** LOCK MUTEX *********/
|
||||
|
||||
std::list<TouStunPeer>::iterator it;
|
||||
int i;
|
||||
|
@ -881,9 +721,9 @@ bool UdpSorter::getStunPeer(int idx, std::string &id,
|
|||
}
|
||||
|
||||
|
||||
bool UdpSorter::needStunPeers()
|
||||
bool UdpStunner::needStunPeers()
|
||||
{
|
||||
RsStackMutex stack(sortMtx); /********** LOCK MUTEX *********/
|
||||
RsStackMutex stack(stunMtx); /********** LOCK MUTEX *********/
|
||||
|
||||
return (mStunList.size() < TOU_STUN_MIN_PEERS);
|
||||
}
|
|
@ -1,13 +1,15 @@
|
|||
#ifndef RS_UDP_STUN_H
|
||||
#define RS_UDP_STUN_H
|
||||
/*
|
||||
* libretroshare/src/tcponudp: udpsorter.h
|
||||
* tcponudp/udpstunner.h
|
||||
*
|
||||
* TCP-on-UDP (tou) network interface for RetroShare.
|
||||
* libretroshare.
|
||||
*
|
||||
* Copyright 2007-2008 by Robert Fernie.
|
||||
* Copyright 2010 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.
|
||||
* License Version 3 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
|
||||
|
@ -23,28 +25,16 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include <netinet/in.h>
|
||||
|
||||
#ifndef TOU_UDP_SORTER_H
|
||||
#define TOU_UDP_SORTER_H
|
||||
#include "tcponudp/rsudpstack.h"
|
||||
#include "util/rsthreads.h"
|
||||
#include <string>
|
||||
|
||||
/* universal networking functions */
|
||||
#include "tou_net.h"
|
||||
|
||||
#include <iosfwd>
|
||||
#include <map>
|
||||
|
||||
#include "udplayer.h"
|
||||
/* UdpSorter ..... filters the UDP packets.
|
||||
/* UdpStun.
|
||||
* Stuns peers to determine external addresses.
|
||||
*/
|
||||
|
||||
class UdpPeer
|
||||
{
|
||||
public:
|
||||
virtual void recvPkt(void *data, int size) = 0;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class TouStunPeer
|
||||
{
|
||||
public:
|
||||
|
@ -72,18 +62,12 @@ class TouStunPeer
|
|||
};
|
||||
|
||||
|
||||
class UdpSorter: public UdpReceiver
|
||||
class UdpStunner: public UdpSubReceiver
|
||||
{
|
||||
public:
|
||||
|
||||
UdpSorter(struct sockaddr_in &local);
|
||||
virtual ~UdpSorter() { return; }
|
||||
|
||||
bool resetAddress(struct sockaddr_in &local);
|
||||
|
||||
/* add a TCPonUDP stream */
|
||||
int addUdpPeer(UdpPeer *peer, const struct sockaddr_in &raddr);
|
||||
int removeUdpPeer(UdpPeer *peer);
|
||||
UdpStunner(UdpPublisher *pub);
|
||||
virtual ~UdpStunner() { return; }
|
||||
|
||||
bool setStunKeepAlive(uint32_t required);
|
||||
bool addStunPeer(const struct sockaddr_in &remote, const char *peerid);
|
||||
|
@ -97,22 +81,12 @@ bool needStunPeers();
|
|||
bool externalAddr(struct sockaddr_in &remote, uint8_t &stable);
|
||||
|
||||
/* Packet IO */
|
||||
/* pass-through send packets */
|
||||
int sendPkt(void *data, int size, struct sockaddr_in &to, int ttl);
|
||||
/* callback for recved data (overloaded from UdpReceiver) */
|
||||
virtual void recvPkt(void *data, int size, struct sockaddr_in &from);
|
||||
|
||||
int status(std::ostream &out);
|
||||
|
||||
/* setup connections */
|
||||
int openSocket();
|
||||
virtual int recvPkt(void *data, int size, struct sockaddr_in &from);
|
||||
virtual int status(std::ostream &out);
|
||||
|
||||
/* monitoring / updates */
|
||||
int okay();
|
||||
int tick();
|
||||
|
||||
int close();
|
||||
|
||||
private:
|
||||
|
||||
/* STUN handling */
|
||||
|
@ -120,7 +94,6 @@ bool locked_handleStunPkt(void *data, int size, struct sockaddr_in &from);
|
|||
|
||||
int doStun(struct sockaddr_in stun_addr);
|
||||
|
||||
|
||||
/* stun keepAlive */
|
||||
bool locked_printStunList();
|
||||
bool locked_recvdStun(const struct sockaddr_in &remote, const struct sockaddr_in &extaddr);
|
||||
|
@ -128,13 +101,10 @@ bool locked_checkExternalAddress();
|
|||
|
||||
bool storeStunPeer(const struct sockaddr_in &remote, const char *peerid, bool sent);
|
||||
|
||||
UdpLayer *udpLayer;
|
||||
|
||||
RsMutex sortMtx; /* for all class data (below) */
|
||||
|
||||
struct sockaddr_in laddr; /* local addr */
|
||||
RsMutex stunMtx; /* for all class data (below) */
|
||||
|
||||
struct sockaddr_in eaddr; /* external addr */
|
||||
|
||||
bool eaddrKnown;
|
||||
bool eaddrStable; /* if true then usable. if false -> Symmettric NAT */
|
||||
time_t eaddrTime;
|
||||
|
@ -145,10 +115,6 @@ bool storeStunPeer(const struct sockaddr_in &remote, const char *peerid, bool
|
|||
|
||||
std::list<TouStunPeer> mStunList; /* potentials */
|
||||
|
||||
std::map<struct sockaddr_in, UdpPeer *> streams;
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
/* generic stun functions */
|
Loading…
Add table
Add a link
Reference in a new issue