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:
drbob 2010-07-31 18:14:10 +00:00
parent c1b624832f
commit fcdd7ee113
34 changed files with 627 additions and 1770 deletions

View File

@ -77,8 +77,12 @@ p3BitDht::p3BitDht(std::string id, pqiConnectCb *cb, UdpStack *udpstack, std::st
/* standard dht behaviour */
bdDhtFunctions *stdfns = new bdStdDht();
std::cerr << "p3BitDht() startup ... creating UdpBitDht";
std::cerr << std::endl;
/* create dht */
mUdpBitDht = new UdpBitDht(udpstack, &ownId, dhtVersion, bootstrapfile, stdfns);
udpstack->addReceiver(mUdpBitDht);
/* setup callback to here */
p3BdCallback *bdcb = new p3BdCallback(this);
@ -88,9 +92,18 @@ p3BitDht::p3BitDht(std::string id, pqiConnectCb *cb, UdpStack *udpstack, std::st
p3BitDht::~p3BitDht()
{
//udpstack->removeReceiver(mUdpBitDht);
delete mUdpBitDht;
}
void p3BitDht::start()
{
std::cerr << "p3BitDht::start()";
std::cerr << std::endl;
mUdpBitDht->start(); /* starts up the bitdht thread */
}
/* pqiNetAssist - external interface functions */
void p3BitDht::enable(bool on)
{
@ -122,6 +135,9 @@ bool p3BitDht::getActive()
/* add / remove peers */
bool p3BitDht::findPeer(std::string pid)
{
std::cerr << "p3BitDht::findPeer(" << pid << ")";
std::cerr << std::endl;
/* convert id -> NodeId */
if (!storeTranslation(pid))
{
@ -137,12 +153,15 @@ bool p3BitDht::findPeer(std::string pid)
}
/* add in peer */
mUdpBitDht->addFindNode(&nid, 0);
mUdpBitDht->addFindNode(&nid, BITDHT_QFLAGS_DO_IDLE);
}
bool p3BitDht::dropPeer(std::string pid)
{
std::cerr << "p3BitDht::dropPeer(" << pid << ")";
std::cerr << std::endl;
/* convert id -> NodeId */
bdNodeId nid;
if (!lookupNodeId(pid, &nid))
@ -164,8 +183,11 @@ bool p3BitDht::dropPeer(std::string pid)
/* extract current peer status */
bool p3BitDht::getPeerStatus(std::string id,
struct sockaddr_in &raddr, uint32_t &mode)
struct sockaddr_in &laddr, struct sockaddr_in &raddr,
uint32_t &type, uint32_t &mode)
{
std::cerr << "p3BitDht::getPeerStatus(" << id << ")";
std::cerr << std::endl;
return false;
@ -175,6 +197,9 @@ bool p3BitDht::getExternalInterface(struct sockaddr_in &raddr,
uint32_t &mode)
{
std::cerr << "p3BitDht::getExternalInterface()";
std::cerr << std::endl;
return false;
}
@ -191,6 +216,8 @@ const uint8_t rs_dht_version_data[RS_DHT_VERSION_LEN] = "RS_VERSION_0.5.1";
int p3BitDht::calculateNodeId(const std::string pid, bdNodeId *id)
{
/* generate node id from pid */
std::cerr << "p3BitDht::calculateNodeId() " << pid;
std::cerr << std::endl;
/* use a hash to make it impossible to reverse */
@ -219,6 +246,9 @@ int p3BitDht::lookupNodeId(const std::string pid, bdNodeId *id)
it = mTransToNodeId.find(pid);
if (it == mTransToNodeId.end())
{
std::cerr << "p3BitDht::lookupNodeId() failed";
std::cerr << std::endl;
return 0;
}
*id = it->second;
@ -235,6 +265,9 @@ int p3BitDht::lookupRsId(const bdNodeId *id, std::string &pid)
nit = mTransToRsId.find(*id);
if (nit == mTransToRsId.end())
{
std::cerr << "p3BitDht::lookupRsId() failed";
std::cerr << std::endl;
return 0;
}
pid = nit->second;
@ -286,6 +319,9 @@ int p3BitDht::removeTranslation(const std::string pid)
/********************** Callback Functions **************************/
int p3BitDht::NodeCallback(const bdId *id, uint32_t peerflags)
{
std::cerr << "p3BitDht::NodeCallback()";
std::cerr << std::endl;
/* is it one that we are interested in? */
std::string pid;
/* check for translation */
@ -302,6 +338,9 @@ int p3BitDht::NodeCallback(const bdId *id, uint32_t peerflags)
int p3BitDht::PeerCallback(const bdNodeId *id, uint32_t status)
{
std::cerr << "p3BitDht::PeerCallback()";
std::cerr << std::endl;
/* is it one that we are interested in? */
std::string pid;
/* check for translation */
@ -318,6 +357,9 @@ int p3BitDht::PeerCallback(const bdNodeId *id, uint32_t status)
int p3BitDht::ValueCallback(const bdNodeId *id, std::string key, uint32_t status)
{
std::cerr << "p3BitDht::ValueCallback()";
std::cerr << std::endl;
/* ignore for now */
return 0;
}

View File

@ -47,6 +47,8 @@ class p3BitDht: public pqiNetAssistConnect
virtual ~p3BitDht();
void start(); /* starts up the bitdht thread */
/* pqiNetAssist - external interface functions */
virtual void enable(bool on);
virtual void shutdown(); /* blocking call */
@ -62,12 +64,20 @@ virtual bool findPeer(std::string id);
virtual bool dropPeer(std::string id);
/* extract current peer status */
virtual bool getPeerStatus(std::string id, struct sockaddr_in &raddr,
uint32_t &mode);
virtual bool getPeerStatus(std::string id,
struct sockaddr_in &laddr, struct sockaddr_in &raddr,
uint32_t &type, uint32_t &mode);
virtual bool getExternalInterface(struct sockaddr_in &raddr,
uint32_t &mode);
/* notifyPeer/setExtInterface/Bootstrap/Stun
* hould all be removed from NetAssist?
*/
/* pqiNetAssistConnect - external interface functions */
/* Callback functions - from bitdht */
int NodeCallback(const bdId *id, uint32_t peerflags);
int PeerCallback(const bdNodeId *id, uint32_t status);

View File

@ -1,6 +1,7 @@
TEMPLATE = lib
#CONFIG += staticlib release
CONFIG += staticlib testnetwork
CONFIG += staticlib testnetwork
#CONFIG += staticlib testnetwork bitdht
CONFIG -= qt
TARGET = retroshare
@ -56,11 +57,40 @@ bitdht {
HEADERS += dht/p3bitdht.h
SOURCES += dht/p3bitdht.cc
HEADERS += tcponudp/udppeer.h \
tcponudp/bio_tou.h \
tcponudp/tcppacket.h \
tcponudp/tcpstream.h \
tcponudp/tou.h \
SOURCES += tcponudp/udppeer.cc \
tcponudp/tcppacket.cc \
tcponudp/tcpstream.cc \
tcponudp/tou.cc \
tcponudp/bss_tou.c \
# These two aren't actually used (and don't compile) ....
# but could be useful later
#
# tcponudp/udpstunner.h \
# tcponudp/udpstunner.cc \
#
BITDHT_DIR = ../../libbitdht/src
INCLUDEPATH += . $${BITDHT_DIR}
DEFINES *= RS_USE_BITDHT
}
use_blogs {
HEADERS += services/p3blogs.h
SOURCES += services/p3blogs.cc
DEFINES *= RS_USE_BLOGS
}
PUBLIC_HEADERS = rsiface/rsblogs.h \
rsiface/rschannels.h \
rsiface/rsdisc.h \
@ -301,8 +331,7 @@ HEADERS += serialiser/rsbaseitems.h \
serialiser/rstlvutil.h \
serialiser/rstunnelitems.h
HEADERS += services/p3blogs.h \
services/p3channels.h \
HEADERS += services/p3channels.h \
services/p3chatservice.h \
services/p3disc.h \
services/p3distrib.h \
@ -316,16 +345,9 @@ HEADERS += services/p3blogs.h \
services/p3service.h \
services/p3statusservice.h \
services/p3tunnel.h
# services/p3blogs.h \
HEADERS += tcponudp/bio_tou.h \
tcponudp/extaddrfinder.h \
tcponudp/tcppacket.h \
tcponudp/tcpstream.h \
tcponudp/tou.h \
tcponudp/tou_errno.h \
tcponudp/tou_net.h \
tcponudp/udplayer.h \
tcponudp/udpsorter.h \
HEADERS += tcponudp/extaddrfinder.h \
HEADERS += turtle/p3turtle.h \
turtle/rsturtleitem.h \
@ -349,7 +371,6 @@ SOURCES += dbase/cachestrapper.cc \
dbase/fistore.cc \
dbase/rsexpr.cc
#SOURCES += dht/p3bitdht.cc \
SOURCES += ft/ftchunkmap.cc \
ft/ftcontroller.cc \
@ -427,8 +448,7 @@ SOURCES += serialiser/rsbaseitems.cc \
serialiser/rstlvutil.cc \
serialiser/rstunnelitems.cc
SOURCES += services/p3blogs.cc \
services/p3channels.cc \
SOURCES += services/p3channels.cc \
services/p3chatservice.cc \
services/p3disc.cc \
services/p3distrib.cc \
@ -443,16 +463,6 @@ SOURCES += services/p3blogs.cc \
# removed because getPeer() doesn't exist services/p3tunnel.cc
SOURCES += tcponudp/extaddrfinder.cc \
tcponudp/largefile_tou.cc \
tcponudp/pair_tou.cc \
tcponudp/reset_tou.cc \
tcponudp/tcppacket.cc \
tcponudp/tcpstream.cc \
tcponudp/tou.cc \
tcponudp/tou_net.cc \
tcponudp/udp_server.cc \
tcponudp/udplayer.cc \
tcponudp/udpsorter.cc
SOURCES += turtle/p3turtle.cc \
turtle/rsturtleitem.cc

View File

@ -430,6 +430,10 @@ void p3ConnectMgr::netReset()
* NB: (*it)->reset_listener must be out of the mutex,
* as it calls back to p3ConnMgr.
*/
RsStackMutex stack(connMtx); /****** STACK LOCK MUTEX *******/
struct sockaddr_in iaddr = mOwnState.currentlocaladdr;
#ifdef CONN_DEBUG_RESET
std::cerr << "p3ConnectMgr::netReset() resetting listeners" << std::endl;
@ -437,7 +441,7 @@ void p3ConnectMgr::netReset()
std::list<pqiNetListener *>::const_iterator it;
for(it = mNetListeners.begin(); it != mNetListeners.end(); it++)
{
(*it)->reset_listener();
(*it)->resetListener(iaddr);
#ifdef CONN_DEBUG_RESET
std::cerr << "p3ConnectMgr::netReset() reset listener" << std::endl;
#endif
@ -741,8 +745,10 @@ void p3ConnectMgr::netTick()
void p3ConnectMgr::netUdpInit()
{
// All functionality has been moved elsewhere (pqiNetListener interface)
#if 0
#if defined(CONN_DEBUG_RESET)
std::cerr << "p3ConnectMgr::netUdpInit()" << std::endl;
std::cerr << "p3ConnectMgr::netUdpInit() Does nothing!" << std::endl;
#endif
connMtx.lock(); /* LOCK MUTEX */
@ -750,8 +756,12 @@ void p3ConnectMgr::netUdpInit()
connMtx.unlock(); /* UNLOCK MUTEX */
/* udp port now controlled by udpstack (from libbitdht) */
mUdpStack->resetAddress(iaddr);
/* open our udp port */
tou_init((struct sockaddr *) &iaddr, sizeof(iaddr));
#endif
}
@ -3349,11 +3359,13 @@ bool p3ConnectMgr::netAssistSetAddress( struct sockaddr_in &laddr,
struct sockaddr_in &eaddr,
uint32_t mode)
{
#if 0
std::map<uint32_t, pqiNetAssistConnect *>::iterator it;
for(it = mDhts.begin(); it != mDhts.end(); it++)
{
(it->second)->setExternalInterface(laddr, eaddr, mode);
}
#endif
return true;
}

View File

@ -94,28 +94,33 @@ class pqiNetAssistConnect: public pqiNetAssist
* for the DHT, and must be non-blocking and return quickly
*/
#if 0
virtual void setBootstrapAllowed(bool on) = 0;
virtual bool getBootstrapAllowed() = 0;
/* set key data */
virtual bool setExternalInterface(struct sockaddr_in laddr,
struct sockaddr_in raddr, uint32_t type) = 0;
#endif
/* add / remove peers */
virtual bool findPeer(std::string id) = 0;
virtual bool dropPeer(std::string id) = 0;
/* post DHT key saying we should connect (callback when done) */
virtual bool notifyPeer(std::string id) = 0;
/* extract current peer status */
virtual bool getPeerStatus(std::string id,
struct sockaddr_in &laddr, struct sockaddr_in &raddr,
uint32_t &type, uint32_t &mode) = 0;
#if 0
/* post DHT key saying we should connect (callback when done) */
virtual bool notifyPeer(std::string id) = 0;
/* stun */
virtual bool enableStun(bool on) = 0;
virtual bool addStun(std::string id) = 0;
#endif
protected:
std::string mPeerId;

View File

@ -138,7 +138,7 @@ virtual void peerConnectRequest(std::string id,
class pqiNetListener
{
public:
virtual int reset_listener() = 0;
virtual bool resetListener(struct sockaddr_in &local) = 0;
};

View File

@ -184,38 +184,30 @@ int pqipersongrp::init_listener()
return 1;
}
int pqipersongrp::restart_listener()
bool pqipersongrp::resetListener(struct sockaddr_in &local)
{
#ifdef PGRP_DEBUG
std::cerr << "pqipersongrp::restart_listener()" << std::endl;
std::cerr << "pqipersongrp::resetListener()" << std::endl;
#endif
// stop it,
// change the address.
// restart.
bool haveListener = false;
{ RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/
haveListener = (pqil != NULL);
} /* UNLOCKED */
RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/
if (haveListener)
if (pqil != NULL)
{
#ifdef PGRP_DEBUG
std::cerr << "pqipersongrp::restart_listener() haveListener" << std::endl;
std::cerr << "pqipersongrp::resetListener() haveListener" << std::endl;
#endif
peerConnectState state;
mConnMgr->getOwnNetStatus(state);
RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/
pqil -> resetlisten();
pqil -> setListenAddr(state.currentlocaladdr);
pqil -> setListenAddr(local);
pqil -> setuplisten();
#ifdef PGRP_DEBUG
std::cerr << "pqipersongrp::restart_listener() done!" << std::endl;
std::cerr << "pqipersongrp::resetListener() done!" << std::endl;
#endif
}

View File

@ -54,9 +54,8 @@ class pqipersongrp: public pqihandler, public pqiMonitor, public p3ServiceServer
/*************************** Setup *************************/
/* pqilistener */
virtual int reset_listener() { return restart_listener(); }
virtual bool resetListener(struct sockaddr_in &local); // overloaded from pqiNetListener
int init_listener();
int restart_listener();
int setConfig(p3GeneralConfig *cfg);
int save_config();

View File

@ -172,7 +172,7 @@ void RsServer::run()
lastSec = (int) ts;
// Every second! (UDP keepalive).
tou_tick_stunkeepalive();
//tou_tick_stunkeepalive();
// every five loops (> 5 secs)
if (loop % 5 == 0)

View File

@ -2037,6 +2037,13 @@ RsTurtle *rsTurtle = NULL ;
#include "pqi/p3notify.h" // HACK - moved to pqi for compilation order.
#include "tcponudp/tou.h"
#include "tcponudp/rsudpstack.h"
#ifdef RS_USE_BITDHT
#include "dht/p3bitdht.h"
#include "udp/udpstack.h"
#endif
/****
#define RS_RELEASE 1
@ -2126,6 +2133,29 @@ int RsServer::StartupRetroShare()
// }
pqiNetAssistFirewall *mUpnpMgr = new upnphandler();
//p3DhtMgr *mDhtMgr = new OpenDHTMgr(ownId, mConnMgr, RsInitConfig::configDir);
/**************************** BITDHT ***********************************/
// Make up an address. XXX
struct sockaddr_in tmpladdr;
sockaddr_clear(&tmpladdr);
tmpladdr.sin_port = htons(7812);
rsUdpStack *mUdpStack = new rsUdpStack(tmpladdr);
#ifdef RS_USE_BITDHT
std::string id = "idon't know?";
std::string bootstrapfile = "./bdboot.txt";
p3BitDht *mBitDht = new p3BitDht(id, mConnMgr, mUdpStack, bootstrapfile);
//mUdpStack-stack->addReceiver(udps);
/* construct the rest of the stack */
tou_init(mUdpStack);
#endif
/**************************** BITDHT ***********************************/
SecurityPolicy *none = secpolicy_create();
pqih = new pqisslpersongrp(none, flags);
@ -2206,7 +2236,7 @@ int RsServer::StartupRetroShare()
CachePair cp5(mChannels, mChannels, CacheId(RS_SERVICE_TYPE_CHANNEL, 0));
mCacheStrapper -> addCachePair(cp5);
pqih -> addService(mChannels); /* This must be also ticked as a service */
#ifdef RS_USE_BLOGS
p3Blogs *mBlogs = new p3Blogs(RS_SERVICE_TYPE_QBLOG,
mCacheStrapper, mCacheTransfer, rsFiles,
localcachedir, remotecachedir, blogsdir);
@ -2215,9 +2245,10 @@ int RsServer::StartupRetroShare()
mCacheStrapper -> addCachePair(cp6);
pqih -> addService(mBlogs); /* This must be also ticked as a service */
#endif
#ifndef RS_RELEASE
p3GameLauncher *gameLauncher = new p3GameLauncher(mConnMgr);
pqih -> addService(gameLauncher);
@ -2227,14 +2258,13 @@ int RsServer::StartupRetroShare()
CachePair cp2(photoService, photoService, CacheId(RS_SERVICE_TYPE_PHOTO, 0));
mCacheStrapper -> addCachePair(cp2);
#else
mQblog = NULL;
#endif
/**************************************************************************/
//mConnMgr->addNetAssistConnect(1, mDhtMgr);
#ifdef RS_USE_BITDHT
mConnMgr->addNetAssistConnect(1, mBitDht);
#endif
mConnMgr->addNetAssistFirewall(1, mUpnpMgr);
/**************************************************************************/
@ -2264,7 +2294,9 @@ int RsServer::StartupRetroShare()
mConfigMgr->addConfiguration("msgs.cfg", msgSrv);
mConfigMgr->addConfiguration("chat.cfg", chatSrv);
mConfigMgr->addConfiguration("cache.cfg", mCacheStrapper);
#ifdef RS_USE_BLOGS
mConfigMgr->addConfiguration("blogs.cfg", mBlogs);
#endif
mConfigMgr->addConfiguration("ranklink.cfg", mRanking);
mConfigMgr->addConfiguration("forums.cfg", mForums);
mConfigMgr->addConfiguration("channels.cfg", mChannels);
@ -2340,6 +2372,7 @@ int RsServer::StartupRetroShare()
pqih->init_listener();
mConnMgr->addNetListener(pqih); /* add listener so we can reset all sockets later */
mConnMgr->addNetListener(mUdpStack);
@ -2381,6 +2414,9 @@ int RsServer::StartupRetroShare()
ftserver->ResumeTransfers();
//mDhtMgr->start();
#ifdef RS_USE_BITDHT
mBitDht->start();
#endif
// create loopback device, and add to pqisslgrp.
@ -2402,7 +2438,9 @@ int RsServer::StartupRetroShare()
rsForums = mForums;
rsChannels = mChannels;
rsRanks = new p3Rank(mRanking);
#ifdef RS_USE_BLOGS
rsBlogs = mBlogs;
#endif
rsStatus = new p3Status(mStatusSrv);
#ifndef RS_RELEASE

View 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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View 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;
}

View 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

View File

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

View File

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