Commit 455a25c3 authored by yanmorin's avatar yanmorin
Browse files

New STUN logic to discover true firewall port (NAT)
Send true IP/port in SDP message
Remove big ###### debugging message
New logic to listening on SIP port: 2 tries
parent b39accdc
......@@ -288,6 +288,7 @@ AudioRtpRTX::sendSessionFromMic (unsigned char* data_to_send, int16* data_from_m
// encode divise by two
// Send encoded audio sample over the network
if (compSize > RTP_FRAMES2SEND) { _debug("%d should be %d\n", compSize, _nbFrames);}
//fprintf(stderr, "S");
if (!_sym) {
_sessionSend->putData(timestamp, data_to_send, compSize);
} else {
......@@ -382,6 +383,7 @@ AudioRtpRTX::receiveSessionForSpkr (int16* data_for_speakers_stereo, int16* data
// If the current call is the call which is answered
// Set decoded data to sound device
// expandedSize is in mono/bytes, since we double in stereo, we send two time more
//fprintf(stderr, "R");
audiolayer->putMain(data_for_speakers_stereo, toPut * sizeof(int16));
//Manager::instance().getAudioDriver()->startStream();
......
......@@ -79,7 +79,7 @@ RingBuffer::Put(void* buffer, int toCopy, unsigned short volume) {
copied = 0;
pos = mEnd;
//fprintf(stderr, "P");
while(toCopy) {
block = toCopy;
if (block > (mBufferSize - pos)) // from current pos. to end of buffer
......@@ -130,7 +130,7 @@ RingBuffer::Get(void *buffer, int toCopy, unsigned short volume) {
dest = (samplePtr) buffer;
copied = 0;
//fprintf(stderr, "get start... ");
//fprintf(stderr, "G");
while(toCopy) {
block = toCopy;
if (block > (mBufferSize - mStart))
......
......@@ -57,21 +57,17 @@ public:
void sendRegistrationState(bool state);
void setup();
void sendMessage(const std::string& code, const std::string& seqId, TokenList&
arg);
void sendCallMessage(const std::string& code,
const std::string& sequenceId,
CALLID id,
TokenList arg);
void sendMessage(const std::string& code, const std::string& seqId,
TokenList& arg);
void sendCallMessage(const std::string& code, const std::string& sequenceId,
CALLID id, TokenList arg);
void callFailure(CALLID id);
bool getEvents(const std::string& sequenceId);
bool sendGetEventsEnd();
bool outgoingCall (const std::string& seq,
const std::string& account,
const std::string& callid,
const std::string& to);
bool outgoingCall (const std::string& seq, const std::string& account,
const std::string& callid, const std::string& to);
bool answerCall(const std::string& callId);
bool refuseCall(const std::string& callId);
bool holdCall(const std::string& callId);
......@@ -100,6 +96,7 @@ private:
std::string getCallIdFromId(CALLID id);
CALLID getIdFromCallId(const std::string& callId);
/**
* This callMap is necessary because
* ManagerImpl use callid-int
......
......@@ -1131,32 +1131,32 @@ ManagerImpl::notificationIncomingCall (void) {
/**
* Multi Thread
*/
void
ManagerImpl::getStunInfo (StunAddress4& stunSvrAddr)
bool
ManagerImpl::getStunInfo (StunAddress4& stunSvrAddr, int port)
{
StunAddress4 mappedAddr;
struct in_addr in;
char* addr;
char to[16];
bzero (to, 16);
int fd3, fd4;
bool ok = stunOpenSocketPair(stunSvrAddr,
&mappedAddr,
&fd3,
&fd4);
//int fd3, fd4;
// bool ok = stunOpenSocketPair(stunSvrAddr, &mappedAddr, &fd3, &fd4, port);
int fd1 = stunOpenSocket(stunSvrAddr, &mappedAddr, port);
bool ok = (fd1 == -1 || fd1 == INVALID_SOCKET) ? false : true;
if (ok) {
closesocket(fd3);
closesocket(fd4);
closesocket(fd1);
//closesocket(fd3);
//closesocket(fd4);
_firewallPort = mappedAddr.port;
// Convert ipv4 address to host byte ordering
in.s_addr = ntohl (mappedAddr.addr);
addr = inet_ntoa(in);
_firewallAddr = std::string(addr);
_debug("STUN Firewall: [%s:%d]\n", _firewallAddr.data(), _firewallPort);
return true;
} else {
_debug("Opening a stun socket pair failed\n");
}
return false;
}
bool
......
......@@ -210,11 +210,13 @@ public:
*/
void notificationIncomingCall (void);
/*
* Get information about firewall
* @param stunSvrAddr: stun server
*/
void getStunInfo (StunAddress4& stunSvrAddr);
/*
* Get information about firewall
* @param stunSvrAddr: stun server
* @param port port number to open to test the connection
* @return true if the connection is successful
*/
bool getStunInfo(StunAddress4& stunSvrAddr, int port);
bool useStun (void);
/*
......
......@@ -76,6 +76,14 @@ SipVoIPLink::checkNetwork (void)
return getSipLocalIp();
}
/**
* Steps:
* 1. Init eXosip
* 2. Try to listen two times on a port
* if we use stun, we check if we can use 5060, before connecting to eXosip...
* if we can't we check on a random port
*/
bool
SipVoIPLink::init(void)
{
......@@ -86,39 +94,54 @@ SipVoIPLink::init(void)
_started = true;
srand (time(NULL));
// second parameter, NULL is "::" for ipv6 and "0.0.0.0" for ipv4, we can put INADDR_ANY
int i;
i = eXosip_listen_addr(IPPROTO_UDP, INADDR_ANY, DEFAULT_SIP_PORT, AF_INET, 0);
if (i != 0) {
i = eXosip_listen_addr(IPPROTO_UDP, INADDR_ANY, RANDOM_SIP_PORT, AF_INET, 0);
if (i != 0) {
_debug("Could not initialize transport layer\n");
return false;
} else {
_debug("VoIP Link listen on random port %d\n", RANDOM_SIP_PORT);
}
} else {
_debug("VoIP Link listen on port %d\n", DEFAULT_SIP_PORT);
}
// Set user agent
std::string tmp = std::string(PROGNAME_GLOBAL) + "/" + std::string(SFLPHONED_VERSION);
eXosip_set_user_agent(tmp.data());
// check networking capabilities
if ( !checkNetwork() ) {
return false;
}
// if we useStun and we failed to receive something on port 5060, we try a random port
// If use STUN server, firewall address setup
if (Manager::instance().useStun()) {
if (behindNat() != 1) {
return false;
bool useStun = Manager::instance().useStun();
int port = DEFAULT_SIP_PORT;
int nbTry = 2; // number of times to try to start SIP listener
int iTry = 1; // try number..
do {
if (useStun && !behindNat(port)) {
port = RANDOM_SIP_PORT;
if (!behindNat(port)) {
return false; // hoho we can't use the random sip port too...
}
}
// second parameter, NULL is "::" for ipv6 and "0.0.0.0" for ipv4, we can put INADDR_ANY
i = eXosip_listen_addr(IPPROTO_UDP, INADDR_ANY, port, AF_INET, 0);
if (i != 0) {
_debug("SIP ERROR: [%d/%d] could not initialize SIP listener on port %d\n", iTry, nbTry, port);
port = RANDOM_SIP_PORT;
}
} while ( i != 0 && iTry < nbTry );
if ( i != 0 ) { // we didn't succeeded
_debug("SIP FAILURE: SIP failed to listen on port %d\n", port);
return false;
}
_debug("SIP Init: listening on port %d\n", port);
if (useStun) {
// This method is used to replace contact address with the public address of your NAT
// it should be call after eXosip_listen_addr
eXosip_masquerade_contact((Manager::instance().getFirewallAddress()).data(), Manager::instance().getFirewallPort());
}
_debug("SIP VoIP Link: listen to SIP Events\n");
// Set user agent
std::string tmp = std::string(PROGNAME_GLOBAL) + "/" + std::string(SFLPHONED_VERSION);
eXosip_set_user_agent(tmp.data());
_debug("SIP Init: starting loop thread (SIP events)\n");
_evThread->start();
return true;
}
......@@ -652,10 +675,7 @@ SipVoIPLink::getEvent (void)
CALLID id = 0;
int returnValue = EXOSIP_ERROR_NO;
_debug("#############################################\n"
" SipEvent #%03d %s\n"
" #############################################\n",
event->type, event->textinfo);
_debug("SIP Event: #%03d %s\n", event->type, event->textinfo);
switch (event->type) {
// IP-Phone user receives a new call
......@@ -668,7 +688,7 @@ SipVoIPLink::getEvent (void)
setLocalPort(RANDOM_LOCAL_PORT);
} else {
// If there is a firewall
if (behindNat() != 0) {
if (behindNat(DEFAULT_LOCAL_PORT) != 0) {
setLocalPort(Manager::instance().getFirewallPort());
} else {
returnValue = EXOSIP_ERROR_STD;
......@@ -1281,8 +1301,8 @@ SipVoIPLink::sdp_off_hold_call (sdp_message_t * sdp)
return 0;
}
int
SipVoIPLink::behindNat (void)
bool
SipVoIPLink::behindNat(int port)
{
StunAddress4 stunSvrAddr;
stunSvrAddr.addr = 0;
......@@ -1299,9 +1319,7 @@ SipVoIPLink::behindNat (void)
// Firewall address
//_debug("STUN server: %s\n", svr.data());
Manager::instance().getStunInfo(stunSvrAddr);
return 1;
return Manager::instance().getStunInfo(stunSvrAddr, port);
}
/**
......@@ -1413,17 +1431,18 @@ SipVoIPLink::startCall(CALLID id, const std::string& from, const std::string& to
_debug(" Setting local port to random: %d\n",_localPort);
} else {
// If use Stun server
if (behindNat() != 0) {
if (behindNat(_localPort)) {
setLocalIpAddress(Manager::instance().getFirewallAddress());
setLocalPort(Manager::instance().getFirewallPort());
_debug(" Setting local port to firewall port: %d\n", _localPort);
_debug(" Setting local port to firewall port: %d\n", _localPort);
} else {
return -1;
}
}
// Set local audio port for sipcall(id)
sipcall->setLocalAudioPort(_localPort);
sipcall->setLocalIp(getLocalIpAddress());
sipcall->setLocalAudioPort(_localPort);
eXosip_lock();
int i = eXosip_call_build_initial_invite (&invite, (char*)to.data(),
......
......@@ -132,10 +132,11 @@ private:
* If you are behind a NAT, you have to use STUN server, specified in
* STUN configuration(you can change this one by default) to give you an
* public IP address and assign a port number.
* @param port : on which port we want to listen to
*
* Return 0 if an error occured and 1 if no error.
* Return false if an error occured and true if no error.
*/
int behindNat (void);
bool behindNat(int port);
/*
* Return -1 if an error occured and 0 if no error
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment