/*
The oRTP library is an RTP (Realtime Transport Protocol - rfc3550) stack.
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser 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
*/
/* ====================================================================
* The Vovida Software License, Version 1.0
*
* Copyright (c) 2000 Vovida Networks, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The names "VOCAL", "Vovida Open Communication Application Library",
* and "Vovida Open Communication Application Library (VOCAL)" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact vocal@vovida.org.
*
* 4. Products derived from this software may not be called "VOCAL", nor
* may "VOCAL" appear in their name, without prior written
* permission of Vovida Networks, Inc.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA
* NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
* IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* ====================================================================
*
* This software consists of voluntary contributions made by Vovida
* Networks, Inc. and many individuals on behalf of Vovida Networks,
* Inc. For more information on Vovida Networks, Inc., please see
* .
*
*/
#include
#include
#include
#if !defined(_WIN32) && !defined(_WIN32_WCE)
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#endif
#include
#include
#if defined(_WIN32) || defined(_WIN32_WCE)
#include
#include
/* #include */
#else
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#endif
#include
#include "mediastreamer2/stun_udp.h"
#include "ortp/ortp.h"
#if !defined(_WIN32) && !defined(_WIN32_WCE)
int getErrno() { return errno; }
#else
int getErrno() { return WSAGetLastError(); }
#endif
Socket
openPort( unsigned short port, unsigned int interfaceIp )
{
struct sockaddr_in addr;
Socket fd;
fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
if ( fd == INVALID_SOCKET )
{
ortp_error("stun_udp: Could not create a UDP socket");
return INVALID_SOCKET;
}
memset((char*) &(addr),0, sizeof((addr)));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons(port);
if ( (interfaceIp != 0) &&
( interfaceIp != 0x100007f ) )
{
addr.sin_addr.s_addr = htonl(interfaceIp);
//ortp_debug("Binding to interface 0x%lu\n",(unsigned long) htonl(interfaceIp));
}
if ( bind( fd,(struct sockaddr*)&addr, sizeof(addr)) != 0 )
{
int e = getErrno();
switch (e)
{
case 0:
{
ortp_error("stun_udp: Could not bind socket");;
return INVALID_SOCKET;
}
case EADDRINUSE:
{
ortp_error("stun_udp: Port %i for receiving UDP is in use", port);
return INVALID_SOCKET;
}
break;
case EADDRNOTAVAIL:
{
ortp_error("stun_udp: Cannot assign requested address");
return INVALID_SOCKET;
}
break;
default:
{
#if !defined(_WIN32_WCE)
ortp_error("stun_udp: Could not bind UDP receive port Error=%i %s",
e, strerror(e));
#else
ortp_error("stun_udp: Could not bind UDP receive port Error=%i",
e);
#endif
return INVALID_SOCKET;
}
break;
}
}
ortp_debug("stun: opened port %i with fd %i\n", port, fd);
/* assert( fd != INVALID_SOCKET ); */
return fd;
}
bool_t
getMessage( Socket fd, char* buf, int* len,
unsigned int* srcIp, unsigned short* srcPort)
{
/* assert( fd != INVALID_SOCKET ); */
int originalSize = *len;
struct sockaddr_in from;
int fromLen = sizeof(from);
int err;
struct timeval tv;
fd_set fdSet;
#if defined(_WIN32) || defined(_WIN32_WCE)
unsigned int fdSetSize;
#else
int fdSetSize;
#endif
if (originalSize <= 0)
{
return FALSE;
}
tv.tv_sec=1;
tv.tv_usec=0; /* 150 ms */
FD_ZERO(&fdSet); fdSetSize=0;
FD_SET(fd,&fdSet); fdSetSize = (unsigned int)fd+1;
err = select(fdSetSize, &fdSet, NULL, NULL, &tv);
if ( err == SOCKET_ERROR )
{
int e = getErrno();
switch (e)
{
case ENOTSOCK:
ortp_error("stun_udp: Error fd not a socket");
break;
case ECONNRESET:
ortp_error("stun_udp: Error connection reset - host not reachable");
break;
default:
ortp_error("stun_udp: Socket Error=%i", e);
}
return FALSE;
}
if (err==0)
{
ortp_error("stun_udp: Connection timeout with stun server!");
*len = 0;
return FALSE;
}
if (FD_ISSET (fd, &fdSet))
{
*len = recvfrom(fd,
buf,
originalSize,
0,
(struct sockaddr *)&from,
(socklen_t*)&fromLen);
if ( *len == SOCKET_ERROR )
{
int e = getErrno();
switch (e)
{
case ENOTSOCK:
ortp_error("stun_udp: Error fd not a socket");
break;
case ECONNRESET:
ortp_error("stun_udp: Error connection reset - host not reachable");
break;
default:
ortp_error("stun_udp: Socket Error=%i", e);
}
return FALSE;
}
if ( *len < 0 )
{
ortp_error("stun_udp: socket closed? negative len");
return FALSE;
}
if ( *len == 0 )
{
ortp_error("stun_udp: socket closed? zero len");
return FALSE;
}
*srcPort = ntohs(from.sin_port);
*srcIp = ntohl(from.sin_addr.s_addr);
if ( (*len)+1 >= originalSize )
{
ortp_error("stun_udp: Received a message that was too large");
return FALSE;
}
buf[*len]=0;
return TRUE;
}
return FALSE;
}
bool_t
sendMessage( Socket fd, char* buf, int l,
unsigned int dstIp, unsigned short dstPort)
{
int s;
if (fd == INVALID_SOCKET)
return FALSE;
if ( dstPort == 0 )
{
/* sending on a connected port */
s = send(fd,buf,l,0);
}
else
{
struct sockaddr_in to;
int toLen = sizeof(to);
if (dstIp == 0)
{
ortp_error("stun_udp: invalid IP provided (dstIP==0)");
return FALSE;
}
memset(&to,0,toLen);
to.sin_family = AF_INET;
to.sin_port = htons(dstPort);
to.sin_addr.s_addr = htonl(dstIp);
s = sendto(fd, buf, l, 0,(struct sockaddr*)&to, toLen);
}
if ( s == SOCKET_ERROR )
{
int e = getErrno();
switch (e)
{
case ECONNREFUSED:
case EHOSTDOWN:
case EHOSTUNREACH:
{
/* quietly ignore this */
}
break;
case EAFNOSUPPORT:
{
ortp_error("stun_udp: err EAFNOSUPPORT in send");
}
break;
default:
{
#if !defined(_WIN32_WCE)
ortp_error("stun_udp: err %i %s in send", e, strerror(e));
#else
ortp_error("stun_udp: err %i in send", e);
#endif
}
}
return FALSE;
}
if ( s == 0 )
{
ortp_error("stun_udp: no data sent in send");
return FALSE;
}
if ( s != l )
{
ortp_error("stun_udp: only %i out of %i bytes sent", s, l);
return FALSE;
}
return TRUE;
}
void
initNetwork()
{
#if defined(_WIN32) || defined(_WIN32_WCE)
WORD wVersionRequested = MAKEWORD( 2, 2 );
WSADATA wsaData;
int err;
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 )
{
/* could not find a usable WinSock DLL */
ortp_error("stun_udp: Could not load winsock");
}
/* Confirm that the WinSock DLL supports 2.2.*/
/* Note that if the DLL supports versions greater */
/* than 2.2 in addition to 2.2, it will still return */
/* 2.2 in wVersion since that is the version we */
/* requested. */
if ( LOBYTE( wsaData.wVersion ) != 2 ||
HIBYTE( wsaData.wVersion ) != 2 )
{
/* Tell the user that we could not find a usable */
/* WinSock DLL. */
WSACleanup( );
ortp_error("stun_udp: Wrong winsock (!= 2.2) version");
}
#endif
}
/* ====================================================================
* The Vovida Software License, Version 1.0
*
* Copyright (c) 2000 Vovida Networks, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The names "VOCAL", "Vovida Open Communication Application Library",
* and "Vovida Open Communication Application Library (VOCAL)" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact vocal@vovida.org.
*
* 4. Products derived from this software may not be called "VOCAL", nor
* may "VOCAL" appear in their name, without prior written
* permission of Vovida Networks, Inc.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA
* NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
* IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* ====================================================================
*
* This software consists of voluntary contributions made by Vovida
* Networks, Inc. and many individuals on behalf of Vovida Networks,
* Inc. For more information on Vovida Networks, Inc., please see
* .
*
*/
/* Local Variables:
mode:c
c-file-style:"ellemtel"
c-file-offsets:((case-label . +))
indent-tabs-mode:nil
End:
*/