⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 stun.c

📁 mediastreamer2是开源的网络传输媒体流的库
💻 C
📖 第 1 页 / 共 5 页
字号:
 /*  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 * <http://www.vovida.org/>. * */#ifdef HAVE_CONFIG_H#include "ortp-config.h"#endif#ifndef _WIN32_WCE#include <errno.h>#endif#include <assert.h>#if defined(WIN32) || defined(_WIN32_WCE)#include <winsock2.h>#include <stdlib.h>/* #include <io.h> */#include <time.h>#include <ctype.h> /*for isdigit() */#else#include <stdlib.h>#include <unistd.h>#include <string.h>#include <sys/ioctl.h>#include <sys/socket.h>#include <sys/time.h>#include <sys/types.h> #include <arpa/inet.h>#include <fcntl.h>#include <netdb.h>#include <netinet/in.h>#include <arpa/nameser.h>#include <resolv.h>#include <net/if.h>#endif#if !defined(HAVE_OPENSSL_HMAC_H) || !defined(HAVE_OPENSSL_MD5_H)#define NOSSL 1#endif#include "ortp/stun_udp.h"#include "ortp/stun.h"#include "ortp/ortp.h"static char *ipaddr(const StunAddress4 *addr){   static char tmp[512];   struct in_addr inaddr;   char *atmp;   inaddr.s_addr = htonl(addr->addr);   atmp = (char *)inet_ntoa(inaddr);      snprintf(tmp, 512, "%s:%i", atmp, addr->port);   return tmp;}static voidcomputeHmac_longterm(char* hmac, const char* input, int length,                     const char *username, const char *realm, const char *password);static voidcomputeHmac_shortterm(char* hmac, const char* input, int length, const char* key);static bool_t stunParseAtrAddress( char* body, unsigned int hdrLen,  StunAtrAddress4 *result ){   if ( hdrLen != 8 )   {      ortp_error("stun: hdrLen wrong for Address\n");      return FALSE;   }   result->pad = *body++;   result->family = *body++;   if (result->family == IPv4Family)   {      UInt16 nport;      UInt32 naddr;      memcpy(&nport, body, 2); body+=2;      result->ipv4.port = ntohs(nport);      memcpy(&naddr, body, 4); body+=4;      result->ipv4.addr = ntohl(naddr);      return TRUE;   }   else if (result->family == IPv6Family)   {      ortp_error("stun: ipv6 not supported\n");   }   else   {      ortp_error("stun: bad address family: %i\n", result->family);   }	   return FALSE;}static bool_t stunParseAtrChangeRequest( char* body, unsigned int hdrLen,  StunAtrChangeRequest *result ){   if ( hdrLen != 4 )   {     /* ortp_error("stun: hdr length = %i expecting %i\n",hdrLen, sizeof(result)); */		      ortp_error("stun: Incorrect size for SA_CHANGEREQUEST");      return FALSE;   }   else   {      memcpy(&result->value, body, 4);      result->value = ntohl(result->value);      return TRUE;   }}static bool_t stunParseAtrError( char* body, unsigned int hdrLen,  StunAtrError *result ){   if ( hdrLen >= sizeof(StunAtrError) )   {      ortp_error("stun: Incorrect size for SA_ERRORCODE");      return FALSE;   }   else   {      memcpy(&result->pad, body, 2); body+=2;      result->pad = ntohs(result->pad);      result->errorClass = *body++;      result->number = *body++;		      result->sizeReason = hdrLen - 4;      memcpy(&result->reason, body, result->sizeReason);      result->reason[result->sizeReason] = 0;      return TRUE;   }}static bool_t stunParseAtrUnknown( char* body, unsigned int hdrLen,  StunAtrUnknown *result ){   if ( hdrLen >= sizeof(result) )   {      ortp_error("stun: Incorrect size for SA_UNKNOWNATTRIBUTE");      return FALSE;   }   else   {      int i;      if (hdrLen % 4 != 0) return FALSE;      result->numAttributes = hdrLen / 4;      for (i=0; i<result->numAttributes; i++)      {         memcpy(&result->attrType[i], body, 2); body+=2;         result->attrType[i] = ntohs(result->attrType[i]);      }      return TRUE;   }}static bool_t stunParseAtrString( char* body, unsigned int hdrLen,  StunAtrString *result ){   if ( hdrLen >= STUN_MAX_STRING )   {      ortp_error("stun: String is too large");      return FALSE;   }   else   {      result->sizeValue = hdrLen;      memcpy(&result->value, body, hdrLen);      result->value[hdrLen] = 0;      return TRUE;   }}static bool_t stunParseAtrIntegrity( char* body, unsigned int hdrLen,  StunAtrIntegrity *result ){   if ( hdrLen != 20)   {      ortp_error("stun: SA_MESSAGEINTEGRITY must be 20 bytes");      return FALSE;   }   else   {      memcpy(&result->hash, body, hdrLen);      return TRUE;   }}static bool_t turnParseAtrChannelNumber( char* body, unsigned int hdrLen,  TurnAtrChannelNumber *result ){   if ( hdrLen >= sizeof(result) )   {      ortp_error("stun: Incorrect size for TA_CHANNELNUMBER");      return FALSE;   }   else   {      if (hdrLen % 4 != 0) return FALSE;      memcpy(&result->channelNumber, body, 2);      body+=2;      result->channelNumber = ntohs(result->channelNumber);      memcpy(&result->rffu, body, 2);      body+=2;      result->rffu = ntohs(result->rffu);      return TRUE;   }}static bool_t turnParseAtrLifetime( char* body, unsigned int hdrLen,  TurnAtrLifetime *result ){   if ( hdrLen != sizeof(result) )   {      ortp_error("stun: Incorrect size for TA_LIFETIME");      return FALSE;   }   else   {      memcpy(&result->lifetime, body, 4);      result->lifetime = ntohl(result->lifetime);      return TRUE;   }}static bool_t turnParseAtrData( char* body, unsigned int hdrLen,  TurnAtrData *result ){   if ( hdrLen >= 1500 )   {      ortp_error("stun: Incorrect size for TA_DATA");      return FALSE;   }   else   {      result->sizeValue = hdrLen;      memcpy(&result->value, body, hdrLen);      result->value[hdrLen] = 0;      return TRUE;   }}static bool_t turnParseAtrRequestedTransport( char* body, unsigned int hdrLen,  TurnAtrRequestedTransport *result ){   if ( hdrLen != 4 )   {      ortp_error("stun: Incorrect size for TA_REQUESTEDTRANSPORT");      return FALSE;   }   result->proto = *body++;   result->pad1 = *body++;   result->pad2 = *body++;   result->pad3 = *body++;   return TRUE;}#ifdef ORTP_BIGENDIAN#define htonq(n) n#define ntohq(n) n#else /* little endian */static inline UInt64htonq (UInt64 v){  return htonl ((UInt32) (v >> 32))    | (UInt64) htonl ((UInt32) v) << 32;}static inline UInt64ntohq (UInt64 v){  return ntohl ((UInt32) (v >> 32))    | (UInt64) ntohl ((UInt32) v) << 32;}#endif /* little endian */static bool_t turnParseAtrReservationToken( char* body, unsigned int hdrLen,  TurnAtrReservationToken *result ){  if ( hdrLen != 8 )  {    ortp_error("stun: Incorrect size for TA_RESERVATIONTOKEN");    return FALSE;  }  memcpy(&result->value, body, 8);  result->value = ntohq(result->value);  return TRUE;}static bool_t turnParseAtrFingerprint( char* body, unsigned int hdrLen, TurnAtrFingerprint *result ){  if ( hdrLen != 4 )  {    ortp_error("stun: Incorrect size for SA_FINGERPRINT");    return FALSE;  }  memcpy(&result->fingerprint, body, 4);  result->fingerprint = ntohl(result->fingerprint);  return TRUE;}static bool_t iceParseAtrPriority( char* body, unsigned int hdrLen, IceAtrPriority *result ){  if ( hdrLen != sizeof(result) )  {    ortp_error("stun: Incorrect size for ICEA_PRIORITY");    return FALSE;  }  memcpy(&result->priority, body, 4);  result->priority = ntohl(result->priority);  return TRUE;}static bool_t iceParseAtrIceControll( char* body, unsigned int hdrLen, IceAtrIceControll *result ){  if ( hdrLen != sizeof(result) )  {    ortp_error("stun: Incorrect size for ICEA_ICECONTROLLED/ICEA_ICECONTROLLING");    return FALSE;  }  memcpy(&result->value, body, 8);  result->value = ntohq(result->value);  return TRUE;} bool_tstunParseMessage( char* buf, unsigned int bufLen, StunMessage *msg){   char* body;   unsigned int size;	 ortp_debug("stun: Received stun message: %i bytes\n", bufLen);   memset(msg, 0, sizeof(msg));	   if (sizeof(StunMsgHdr) > bufLen)   {      ortp_warning("stun: message too short\n");      return FALSE;   }   memcpy(&msg->msgHdr, buf, sizeof(StunMsgHdr));   msg->msgHdr.msgType = ntohs(msg->msgHdr.msgType);   msg->msgHdr.msgLength = ntohs(msg->msgHdr.msgLength);   if (msg->msgHdr.msgLength + sizeof(StunMsgHdr) != bufLen)   {      ortp_warning("stun: Message header length doesn't match message size: %i - %i\n", msg->msgHdr.msgLength, bufLen);      return FALSE;   }   body = buf + sizeof(StunMsgHdr);   size = msg->msgHdr.msgLength;	   /*ortp_message("stun: bytes after header = %i\n", size); */	   while ( size > 0 )   {      /* !jf! should check that there are enough bytes left in the buffer */		      StunAtrHdr* attr = (StunAtrHdr*)body; /*reinterpret_cast<StunAtrHdr*>(body);*/		      unsigned int attrLen = ntohs(attr->length);      int atrType = ntohs(attr->type);		      if ( attrLen+4 > size )       {         ortp_error("stun: claims attribute is larger than size of message (attribute type=%i)\n", atrType);         return FALSE;      }		      body += 4; /* skip the length and type in attribute header */      size -= 4;		      if (atrType == SA_MAPPEDADDRESS)      {            msg->hasMappedAddress = TRUE;            if ( stunParseAtrAddress(  body,  attrLen,  &msg->mappedAddress )== FALSE )            {               ortp_error("stun: problem parsing SA_MAPPEDADDRESS\n");               return FALSE;            }            else            {               ortp_debug("stun: SA_MAPPEDADDRESS = %s\n", ipaddr(&msg->mappedAddress.ipv4));            }					      }      else if (atrType == SA_RESPONSEADDRESS)      {            msg->hasResponseAddress = TRUE;            if ( stunParseAtrAddress(  body,  attrLen,  &msg->responseAddress )== FALSE )            {               ortp_error("stun: problem parsing SA_RESPONSEADDRESS");               return FALSE;            }            else            {               ortp_debug("stun: SA_RESPONSEADDRESS = %s\n", ipaddr(&msg->responseAddress.ipv4));            }      }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -