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

📄 stun.c

📁 mediastreamer2是开源的网络传输媒体流的库
💻 C
📖 第 1 页 / 共 5 页
字号:
   /* set up information for default response */	   memset( &req, 0 , sizeof(req) );   memset( resp, 0 , sizeof(*resp) );	   *changeIp = FALSE;   *changePort = FALSE;	   ok = stunParseMessage( buf,bufLen, &req);      if (!ok)      /* Complete garbage, drop it on the floor */   {      ortp_error("stun: Request did not parse");      return FALSE;   }   //ortp_debug("stun: Request parsed ok");	   mapped = req.mappedAddress.ipv4;   respondTo = req.responseAddress.ipv4;   flags = req.changeRequest.value;	   if (req.msgHdr.msgType==(STUN_METHOD_BINDING|STUN_REQUEST))   {         if (!req.hasMessageIntegrity)         {            //ortp_debug("stun: BindRequest does not contain SA_MESSAGEINTEGRITY");				            if (0) /* !jf! mustAuthenticate */            {               ortp_error("stun: Received BindRequest with no SA_MESSAGEINTEGRITY. Sending 401.");               stunCreateErrorResponse(resp, 4, 1, "Missing SA_MESSAGEINTEGRITY");               return TRUE;            }         }         else         {            if (!req.hasUsername)            {               ortp_error("stun: No UserName. Send 432.");               stunCreateErrorResponse(resp, 4, 32, "No UserName and contains SA_MESSAGEINTEGRITY");               return TRUE;            }            else            {               //ortp_debug("stun: Validating username: %s", req.username.value );               /* !jf! could retrieve associated password from provisioning here */               if (strcmp(req.username.value, "test") == 0)               {                  if (0)                  {                     /* !jf! if the credentials are stale */                     stunCreateErrorResponse(resp, 4, 30, "Stale credentials on BindRequest");                     return TRUE;                  }                  else                  {                     unsigned char hmac[20];                     //ortp_debug("stun: Validating SA_MESSAGEINTEGRITY");                     /* need access to shared secret */#ifndef NOSSL                     {                        unsigned int hmacSize=20;                        HMAC(EVP_sha1(),                              "1234", 4,                              (const unsigned char*) buf, bufLen-20-4,                              hmac, &hmacSize);                        /*HMAC(EVP_sha1(),                              "1234", 4,                              reinterpret_cast<const unsigned char*>(buf), bufLen-20-4,                              hmac, &hmacSize);                        //assert(hmacSize == 20);			*/                     }#endif							                     if (memcmp(buf, hmac, 20) != 0)                     {                        ortp_error("stun: SA_MESSAGEINTEGRITY is bad. Sending ");                        stunCreateErrorResponse(resp, 4, 3, "Unknown username. Try test with password 1234");                        return TRUE;                     }							                     /* need to compute this later after message is filled in */                     resp->hasMessageIntegrity = TRUE;                     /* assert(req.hasUsername); */                     resp->hasUsername = TRUE;                     resp->username = req.username; /* copy username in */                  }               }               else               {                  ortp_error("stun: Invalid username: %s Send 430", req.username.value);                }            }         }			         /* TODO !jf! should check for unknown attributes here and send 420 listing the            unknown attributes. */			         if ( respondTo.port == 0 )         {            /* respondTo = from; */            memcpy(&respondTo, from, sizeof(StunAddress4));         }         if ( mapped.port == 0 )          {            /* mapped = from; */            memcpy(&mapped, from, sizeof(StunAddress4));         }         *changeIp   = ( flags & ChangeIpFlag )?TRUE:FALSE;         *changePort = ( flags & ChangePortFlag )?TRUE:FALSE;			         //ortp_debug("stun: Request is valid:\n");         //ortp_debug("stun: \t flags= %i\n", flags );         //ortp_debug("stun: \t changeIp= %i\n", *changeIp );         //ortp_debug("stun: \t changePort=%i\n", *changePort );         //ortp_debug("stun: \t from= %i\n", from->addr );         //ortp_debug("stun: \t respond to= %i\n", respondTo.addr );         //ortp_debug("stun: \t mapped= %i\n", mapped.addr );				         /* form the outgoing message */         resp->msgHdr.msgType = (STUN_METHOD_BINDING | STUN_SUCCESS_RESP);         resp->msgHdr.magic_cookie = ntohl(req.msgHdr.magic_cookie);         for (i=0; i<12; i++ )         {            resp->msgHdr.tr_id.octet[i] = req.msgHdr.tr_id.octet[i];         }		         if (1) /* do xorMapped address or not */         {            UInt32 cookie = 0x2112A442;            UInt16 cookie16;            resp->hasXorMappedAddress = TRUE;            cookie16 = ((UInt8*)&cookie)[0]<<8  | ((UInt8*)&cookie)[1];            resp->xorMappedAddress.ipv4.port = mapped.port^cookie16;            resp->xorMappedAddress.ipv4.addr = mapped.addr^cookie;         }                  resp->hasSourceAddress = TRUE;         resp->sourceAddress.ipv4.port = (*changePort) ? altAddr->port : myAddr->port;         resp->sourceAddress.ipv4.addr = (*changeIp)   ? altAddr->addr : myAddr->addr;			         resp->hasChangedAddress = TRUE;         resp->changedAddress.ipv4.port = altAddr->port;         resp->changedAddress.ipv4.addr = altAddr->addr;	         if ( req.hasUsername && req.username.sizeValue > 0 )          {            /* copy username in */            resp->hasUsername = TRUE;            /* assert( req.username.sizeValue % 4 == 0 ); */            /* assert( req.username.sizeValue < STUN_MAX_STRING ); */            memcpy( resp->username.value, req.username.value, req.username.sizeValue );            resp->username.sizeValue = req.username.sizeValue;         }		         if (1) /* add ServerName */         {            const char serverName[] = "oRTP   " STUN_VERSION; /* must pad to mult of 4 */            resp->hasSoftware = TRUE;                        /* assert( sizeof(serverName) < STUN_MAX_STRING ); */            /* cerr << "sizeof serverName is "  << sizeof(serverName) ); */            /* assert( sizeof(serverName)%4 == 0 ); */            memcpy( resp->softwareName.value, serverName, sizeof(serverName));            resp->softwareName.sizeValue = sizeof(serverName);         }         #if 0         if ( req.hasMessageIntegrity & req.hasUsername )           {            /* this creates the password that will be used in the HMAC when then */            /* messages is sent */            stunCreatePassword( &req.username, hmacPassword );         }#endif         if (req.hasUsername && (req.username.sizeValue > 64 ) )         {            UInt32 source;            /* assert( sizeof(int) == sizeof(UInt32) ); */					            sscanf(req.username.value, "%x", &source);            resp->hasReflectedFrom = TRUE;            resp->reflectedFrom.ipv4.port = 0;            resp->reflectedFrom.ipv4.addr = source;         }				         destination->port = respondTo.port;         destination->addr = respondTo.addr;			         return TRUE;		   }   else   {         ortp_error("stun: Unknown or unsupported request ");         return FALSE;   }	   /* assert(0); */   return FALSE;}bool_tstunInitServer(StunServerInfo *info, const StunAddress4 *myAddr, const StunAddress4 *altAddr, int startMediaPort){   /* assert( myAddr.port != 0 ); */   /* assert( altAddr.port!= 0 ); */   /* assert( myAddr.addr  != 0 ); */   /* assert( altAddr.addr != 0 ); */	   /* info->myAddr = myAddr; */   info->myAddr.port = myAddr->port;   info->myAddr.addr = myAddr->addr;   /* info->altAddr = altAddr; */   info->altAddr.port = altAddr->port;   info->altAddr.addr = altAddr->addr;	   info->myFd = INVALID_SOCKET;   info->altPortFd = INVALID_SOCKET;   info->altIpFd = INVALID_SOCKET;   info->altIpPortFd = INVALID_SOCKET;   memset(info->relays, 0, sizeof(info->relays));   if (startMediaPort > 0)   {      int i;      info->relay = TRUE;      for (i=0; i<MAX_MEDIA_RELAYS; ++i)      {         StunMediaRelay* relay = &info->relays[i];         relay->relayPort = startMediaPort+i;         relay->fd = 0;         relay->expireTime = 0;      }   }   else   {      info->relay = FALSE;   }      if ((info->myFd = openPort(myAddr->port, myAddr->addr)) == INVALID_SOCKET)   {      ortp_error("stun: Can't open %i\n", myAddr->addr );      stunStopServer(info);      return FALSE;   }   if ((info->altPortFd = openPort(altAddr->port,myAddr->addr)) == INVALID_SOCKET)   {      ortp_error("stun: Can't open %i\n", myAddr->addr );      stunStopServer(info);      return FALSE;   }         info->altIpFd = INVALID_SOCKET;   if (  altAddr->addr != 0 )   {      if ((info->altIpFd = openPort( myAddr->port, altAddr->addr)) == INVALID_SOCKET)      {         ortp_error("stun: Can't open %i\n", altAddr->addr );         stunStopServer(info);         return FALSE;      }   }      info->altIpPortFd = INVALID_SOCKET;   if (  altAddr->addr != 0 )   {  if ((info->altIpPortFd = openPort(altAddr->port, altAddr->addr)) == INVALID_SOCKET)      {         ortp_error("stun: Can't open %i\n", altAddr->addr );         stunStopServer(info);         return FALSE;      }   }      return TRUE;}voidstunStopServer(StunServerInfo *info){   if (info->myFd > 0) closesocket(info->myFd);   if (info->altPortFd > 0) closesocket(info->altPortFd);   if (info->altIpFd > 0) closesocket(info->altIpFd);   if (info->altIpPortFd > 0) closesocket(info->altIpPortFd);      if (info->relay)   {      int i;      for (i=0; i<MAX_MEDIA_RELAYS; ++i)      {         StunMediaRelay* relay = &info->relays[i];         if (relay->fd)         {            closesocket(relay->fd);            relay->fd = 0;         }      }   }}int stunFindLocalInterfaces(UInt32* addresses,int maxRet){#if defined(WIN32) || defined(_WIN32_WCE) || defined(__sparc__)   return 0;#else   struct ifconf ifc;   int e;   int s = socket( AF_INET, SOCK_DGRAM, 0 );   int len = 100 * sizeof(struct ifreq);      char buf[ 100 * sizeof(struct ifreq) ];   char *ptr;   int tl;   int count=0;   ifc.ifc_len = len;   ifc.ifc_buf = buf;	   e = ioctl(s,SIOCGIFCONF,&ifc);   ptr = buf;   tl = ifc.ifc_len;      while ( (tl > 0) && ( count < maxRet) )   {      struct ifreq* ifr = (struct ifreq *)ptr;      struct ifreq ifr2;      struct sockaddr a;      struct sockaddr_in* addr;         UInt32 ai;      int si = sizeof(ifr->ifr_name) + sizeof(struct sockaddr);      tl -= si;      ptr += si;      /* char* name = ifr->ifr_ifrn.ifrn_name; */      /* cerr << "name = " << name ); */            ifr2 = *ifr;            e = ioctl(s,SIOCGIFADDR,&ifr2);      if ( e == -1 )      {         break;      }            /* cerr << "ioctl addr e = " << e ; */            a = ifr2.ifr_addr;      addr = (struct sockaddr_in*) &a;            ai = ntohl( addr->sin_addr.s_addr );      if ((int)((ai>>24)&0xFF) != 127)      {         addresses[count++] = ai;      }		   }      closesocket(s);      return count;#endif}voidstunBuildReqSimple( StunMessage* msg,                    const StunAtrString *username,                    bool_t changePort, bool_t changeIp, unsigned int id ){   int i;   /* assert( msg ); */   memset( msg , 0 , sizeof(*msg) );	   msg->msgHdr.msgType = (STUN_METHOD_BINDING|STUN_REQUEST);	   msg->msgHdr.magic_cookie = 0x2112A442;   for ( i=0; i<12; i=i+4 )   {      /* assert(i+3<16); */      int r = stunRand();      msg->msgHdr.tr_id.octet[i+0]= r>>0;      msg->msgHdr.tr_id.octet[i+1]= r>>8;      msg->msgHdr.tr_id.octet[i+2]= r>>16;      msg->msgHdr.tr_id.octet[i+3]= r>>24;   }	   if ( id != 0 )   {      msg->msgHdr.tr_id.octet[0] = id;    }	   if (changePort==TRUE || changeIp==TRUE)   {     msg->hasChangeRequest = TRUE;     msg->changeRequest.value =(changeIp?ChangeIpFlag:0) |         (changePort?ChangePortFlag:0);   }   if ( username!=NULL && username->sizeValue > 0 )   {      msg->hasUsername = TRUE;      /* msg->username = username; */      memcpy(&msg->username, username, sizeof(StunAtrString));   }}static void stunSendTest( Socket myFd, StunAddress4 *dest,               const StunAtrString *username, const StunAtrString *password,               int testNum ){    /* assert( dest.addr != 0 ); */   /* assert( dest.port != 0 ); */	   bool_t changePort=FALSE;   bool_t changeIP=FALSE;   bool_t discard=FALSE;   StunMessage req;   char buf[STUN_MAX_MESSAGE_SIZE];   int len = STUN_MAX_MESSAGE_SIZE;      switch (testNum)   {      case 1:      case 10:      case 11:         break;      case 2:         /* changePort=TRUE; */         changeIP=TRUE;         break;      case 3:         changePort=TRUE;         break;      case 4:         changeIP=TRUE;         break;      case 5:         discard=TRUE;         break;      default:         ortp_error("stun: Test %i is unkown\n", testNum);         return ; /* error */   }      memset(&req, 0, sizeof(StunMessage));	   stunBuildReqSimple( &req, username,                        changePort , changeIP ,                        testNum );	   len = stunEncodeMessage( &req, buf, len, password );	   //ortp_debug("stun: About to send msg of len %i to %s\n", len, ipaddr(dest) );	   sendMessage( myFd, buf, len, dest->addr, dest->port );	   /* add some delay so the packets don't get sent too quickly */#if defined(_WIN32_WCE)    Sleep (10);#elif defined(WIN32)/* !cj! TODO - should fix this up in windows */

⌨️ 快捷键说明

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