📄 stun.cxx
字号:
resp->reflectedFrom.ipv4.addr = source; } destination->port = respondTo.port; destination->addr = respondTo.addr; return true; default: if (verbose) clog << "Unknown or unsupported request " << endl; return false; } assert(0); return false;}boolstunInitServer(StunServerInfo& info, const StunAddress4& myAddr, const StunAddress4& altAddr, int startMediaPort, bool verbose ){ assert( myAddr.port != 0 ); assert( altAddr.port!= 0 ); assert( myAddr.addr != 0 ); //assert( altAddr.addr != 0 ); info.myAddr = myAddr; info.altAddr = altAddr; 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) { info.relay = true; for (int 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,verbose)) == INVALID_SOCKET) { if (verbose) clog << "Can't open " << myAddr << endl; stunStopServer(info); return false; } //if (verbose) clog << "Opened " << myAddr.addr << ":" << myAddr.port << " --> " << info.myFd << endl; if ((info.altPortFd = openPort(altAddr.port,myAddr.addr,verbose)) == INVALID_SOCKET) { if (verbose) clog << "Can't open " << myAddr << endl; stunStopServer(info); return false; } //if (verbose) clog << "Opened " << myAddr.addr << ":" << altAddr.port << " --> " << info.altPortFd << endl; info.altIpFd = INVALID_SOCKET; if ( altAddr.addr != 0 ) { if ((info.altIpFd = openPort( myAddr.port, altAddr.addr,verbose)) == INVALID_SOCKET) { if (verbose) clog << "Can't open " << altAddr << endl; stunStopServer(info); return false; } //if (verbose) clog << "Opened " << altAddr.addr << ":" << myAddr.port << " --> " << info.altIpFd << endl;; } info.altIpPortFd = INVALID_SOCKET; if ( altAddr.addr != 0 ) { if ((info.altIpPortFd = openPort(altAddr.port, altAddr.addr,verbose)) == INVALID_SOCKET) { if (verbose) clog << "Can't open " << altAddr << endl; stunStopServer(info); return false; } //if (verbose) clog << "Opened " << altAddr.addr << ":" << altAddr.port << " --> " << info.altIpPortFd << endl;; } 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) { for (int i=0; i<MAX_MEDIA_RELAYS; ++i) { StunMediaRelay* relay = &info.relays[i]; if (relay->fd) { closeSocket(relay->fd); relay->fd = 0; } } }}boolstunServerProcess(StunServerInfo& info, bool verbose){ char msg[STUN_MAX_MESSAGE_SIZE]; int msgLen = sizeof(msg); bool ok = false; bool recvAltIp =false; bool recvAltPort = false; fd_set fdSet; resip::Socket maxFd=0; FD_ZERO(&fdSet); FD_SET(info.myFd,&fdSet); if ( info.myFd >= maxFd ) maxFd=info.myFd+1; FD_SET(info.altPortFd,&fdSet); if ( info.altPortFd >= maxFd ) maxFd=info.altPortFd+1; if ( info.altIpFd != INVALID_SOCKET ) { FD_SET(info.altIpFd,&fdSet); if (info.altIpFd>=maxFd) maxFd=info.altIpFd+1; } if ( info.altIpPortFd != INVALID_SOCKET ) { FD_SET(info.altIpPortFd,&fdSet); if (info.altIpPortFd>=maxFd) maxFd=info.altIpPortFd+1; } if (info.relay) { for (int i=0; i<MAX_MEDIA_RELAYS; ++i) { StunMediaRelay* relay = &info.relays[i]; if (relay->fd) { FD_SET(relay->fd, &fdSet); if ((resip::Socket)relay->fd >= maxFd) { maxFd=relay->fd+1; } } } } if ( info.altIpFd != INVALID_SOCKET ) { FD_SET(info.altIpFd,&fdSet); if (info.altIpFd>=maxFd) maxFd=info.altIpFd+1; } if ( info.altIpPortFd != INVALID_SOCKET ) { FD_SET(info.altIpPortFd,&fdSet); if (info.altIpPortFd>=maxFd) maxFd=info.altIpPortFd+1; } struct timeval tv; tv.tv_sec = 0; tv.tv_usec = 1000; int e = select( maxFd, &fdSet, NULL,NULL, &tv ); if (e < 0) { int err = getErrno(); if (verbose) clog << "Error on select: " << strerror(err) << endl; } else if (e >= 0) { StunAddress4 from; // do the media relaying if (info.relay) { time_t now = time(0); for (int i=0; i<MAX_MEDIA_RELAYS; ++i) { StunMediaRelay* relay = &info.relays[i]; if (relay->fd) { if (FD_ISSET(relay->fd, &fdSet)) { char msg[MAX_RTP_MSG_SIZE]; int msgLen = sizeof(msg); StunAddress4 rtpFrom; ok = getMessage( relay->fd, msg, &msgLen, &rtpFrom.addr, &rtpFrom.port ,verbose); if (ok) { sendMessage(info.myFd, msg, msgLen, relay->destination.addr, relay->destination.port, verbose); relay->expireTime = now + MEDIA_RELAY_TIMEOUT; if ( verbose ) clog << "Relay packet on " << relay->fd << " from " << rtpFrom << " -> " << relay->destination << endl; } } else if (now > relay->expireTime) { closeSocket(relay->fd); relay->fd = 0; } } } } if (FD_ISSET(info.myFd,&fdSet)) { if (verbose) clog << "received on A1:P1" << endl; recvAltIp = false; recvAltPort = false; ok = getMessage( info.myFd, msg, &msgLen, &from.addr, &from.port,verbose ); } else if (FD_ISSET(info.altPortFd, &fdSet)) { if (verbose) clog << "received on A1:P2" << endl; recvAltIp = false; recvAltPort = true; ok = getMessage( info.altPortFd, msg, &msgLen, &from.addr, &from.port,verbose ); } else if ( (info.altIpFd!=INVALID_SOCKET) && FD_ISSET(info.altIpFd,&fdSet)) { if (verbose) clog << "received on A2:P1" << endl; recvAltIp = true; recvAltPort = false; ok = getMessage( info.altIpFd, msg, &msgLen, &from.addr, &from.port ,verbose); } else if ( (info.altIpPortFd!=INVALID_SOCKET) && FD_ISSET(info.altIpPortFd, &fdSet)) { if (verbose) clog << "received on A2:P2" << endl; recvAltIp = true; recvAltPort = true; ok = getMessage( info.altIpPortFd, msg, &msgLen, &from.addr, &from.port,verbose ); } else { return true; } int relayPort = 0; if (info.relay) { for (int i=0; i<MAX_MEDIA_RELAYS; ++i) { StunMediaRelay* relay = &info.relays[i]; if (relay->destination.addr == from.addr && relay->destination.port == from.port) { relayPort = relay->relayPort; relay->expireTime = time(0) + MEDIA_RELAY_TIMEOUT; break; } } if (relayPort == 0) { for (int i=0; i<MAX_MEDIA_RELAYS; ++i) { StunMediaRelay* relay = &info.relays[i]; if (relay->fd == 0) { if ( verbose ) clog << "Open relay port " << relay->relayPort << endl; relay->fd = openPort(relay->relayPort, info.myAddr.addr, verbose); relay->destination.addr = from.addr; relay->destination.port = from.port; relay->expireTime = time(0) + MEDIA_RELAY_TIMEOUT; relayPort = relay->relayPort; break; } } } } if ( !ok ) { if ( verbose ) clog << "Get message did not return a valid message" <<endl; return true; } if ( verbose ) clog << "Got a request (len=" << msgLen << ") from " << from << endl; if ( msgLen <= 0 ) { return true; } bool changePort = false; bool changeIp = false; StunMessage resp; StunAddress4 dest; StunAtrString hmacPassword; hmacPassword.sizeValue = 0; StunAddress4 secondary; secondary.port = 0; secondary.addr = 0; if (info.relay && relayPort) { secondary = from; from.addr = info.myAddr.addr; from.port = relayPort; } ok = stunServerProcessMsg( msg, msgLen, from, secondary, recvAltIp ? info.altAddr : info.myAddr, recvAltIp ? info.myAddr : info.altAddr, &resp, &dest, &hmacPassword, &changePort, &changeIp, verbose ); if ( !ok ) { if ( verbose ) clog << "Failed to parse message" << endl; return true; } char buf[STUN_MAX_MESSAGE_SIZE]; int len = sizeof(buf); len = stunEncodeMessage( resp, buf, len, hmacPassword,verbose ); if ( dest.addr == 0 ) ok=false; if ( dest.port == 0 ) ok=false; if ( ok ) { assert( dest.addr != 0 ); assert( dest.port != 0 ); resip::Socket sendFd; bool sendAltIp = recvAltIp; // send on the received IP address bool sendAltPort = recvAltPort; // send on the received port if ( changeIp ) sendAltIp = !sendAltIp; // if need to change IP, then flip logic if ( changePort ) sendAltPort = !sendAltPort; // if need to change port, then flip logic if ( !sendAltPort ) { if ( !sendAltIp ) { sendFd = info.myFd; } else { sendFd = info.altIpFd; } } else { if ( !sendAltIp ) { sendFd = info.altPortFd; } else { sendFd = info.altIpPortFd; } } if ( sendFd != INVALID_SOCKET ) { sendMessage( sendFd, buf, len, dest.addr, dest.port, verbose ); } } } return true;}int stunFindLocalInterfaces(UInt32* addresses,int maxRet){#if defined(WIN32) || defined(__sparc__) return 0;#else struct ifconf ifc; int s = socket( AF_INET, SOCK_DGRAM, 0 ); const int len = 100 * sizeof(struct ifreq); char buf[ len ]; ifc.ifc_len = len; ifc.ifc_buf = buf; int e = ioctl(s,SIOCGIFCONF,&ifc); char *ptr = buf; int tl = ifc.ifc_len; int count=0; while ( (tl > 0) && ( count < maxRet) ) { struct ifreq* ifr = (struct ifreq *)ptr; int si = sizeof(ifr->ifr_name) + sizeof(struct sockaddr); tl -= si; ptr += si; //char* name = ifr->ifr_ifrn.ifrn_name; //cerr << "name = " << name << endl; struct ifreq ifr2; ifr2 = *ifr; e = ioctl(s,SIOCGIFADDR,&ifr2); if ( e == -1 ) { break; } //cerr << "ioctl addr e = " << e << endl; struct sockaddr a = ifr2.ifr_addr; struct sockaddr_in* addr = (struct sockaddr_in*) &a; UInt32 ai = ntohl( addr->sin_addr.s_addr ); if (int((ai>>24)&0xFF) != 127) { addresses[count++] = ai; } #if 0 cerr << "Detected interface " << int((ai>>24)&0xFF) << "." << int((ai>>16)&0xFF) << "." << int((ai>> 8)&0xFF) << "." << int((ai )&0xFF) << endl;#endif } closeSocket(s); return count;#endif}voidstunBuildReqSimple( StunMessage* msg, const StunAtrString& username, bool changePort, bool changeIp, unsigned int id ){ assert( msg ); memset( msg , 0 , sizeof(*msg) ); msg->msgHdr.msgType = BindRequestMsg; for ( int i=0; i<16; i=i+4 ) { assert(i+3<16); int r = stunRand(); msg->msgHdr.id.octet[i+0]= r>>0; msg->msgHdr.id.octet[i+1]= r>>8;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -