📄 stun.c
字号:
/* 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,verbose)) == INVALID_SOCKET) { ortp_error("stun: Can't open %i\n", myAddr->addr ); stunStopServer(info); return FALSE; } /*if (verbose) ortp_message("stun: Opened " << myAddr->addr << ":" << myAddr->port << " --> " << info->myFd ); */ if ((info->altPortFd = openPort(altAddr->port,myAddr->addr,verbose)) == INVALID_SOCKET) { ortp_error("stun: Can't open %i\n", myAddr->addr ); stunStopServer(info); return FALSE; } /* if (verbose) ortp_message("stun: Opened " << myAddr->addr << ":" << altAddr->port << " --> " << info->altPortFd ); */ info->altIpFd = INVALID_SOCKET; if ( altAddr->addr != 0 ) { if ((info->altIpFd = openPort( myAddr->port, altAddr->addr,verbose)) == INVALID_SOCKET) { ortp_error("stun: Can't open %i\n", altAddr->addr ); stunStopServer(info); return FALSE; } /* if (verbose) ortp_message("stun: Opened " << altAddr->addr << ":" << myAddr->port << " --> " << info->altIpFd ); */ } info->altIpPortFd = INVALID_SOCKET; if ( altAddr->addr != 0 ) { if ((info->altIpPortFd = openPort(altAddr->port, altAddr->addr,verbose)) == INVALID_SOCKET) { ortp_error("stun: Can't open %i\n", altAddr->addr ); stunStopServer(info); return FALSE; } /* if (verbose) ortp_message("stun: Opened " << altAddr->addr << ":" << altAddr->port << " --> " << info->altIpPortFd ); */ } 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; } } }}#if 0 /* no usefull here */bool_tstunServerProcess(StunServerInfo *info, bool_t verbose){ char msg[STUN_MAX_MESSAGE_SIZE]; int msgLen = sizeof(msg); bool_t ok = FALSE; bool_t recvAltIp =FALSE; bool_t recvAltPort = FALSE; fd_set fdSet; #if defined(_WIN32) || defined(_WIN32_WCE) unsigned int maxFd=0;#else int maxFd=0;#endif struct timeval tv; int e; 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) { int i; for (i=0; i<MAX_MEDIA_RELAYS; ++i) { StunMediaRelay* relay = &info->relays[i]; if (relay->fd) { FD_SET(relay->fd, &fdSet); if (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; } tv.tv_sec = 0; tv.tv_usec = 1000; e = select( maxFd, &fdSet, NULL,NULL, &tv ); if (e < 0) { int err = getErrno();#if !defined(_WIN32_WCE) ortp_error("stun: Error on select: %s\n", strerror(err) );#else ortp_error("stun: Error on select: %i\n", err );#endif } else if (e >= 0) { StunAddress4 from; int relayPort = 0; bool_t changePort = FALSE; bool_t changeIp = FALSE; StunMessage resp; StunAddress4 dest; StunAtrString hmacPassword; StunAddress4 secondary; char buf[STUN_MAX_MESSAGE_SIZE]; int len = sizeof(buf); hmacPassword.sizeValue = 0; secondary.port = 0; secondary.addr = 0; /* do the media relaying */ if (info->relay) { time_t now; int i;#if !defined(_WIN32_WCE) now = time(0);#else DWORD timemillis = GetTickCount(); now = timemillis/1000;#endif for (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 ) ortp_message("stun: Relay packet on %i from %i -> %i", relay->fd, rtpFrom.addr, relay->destination.addr ); } } else if (now > relay->expireTime) { closesocket(relay->fd); relay->fd = 0; } } } } if (FD_ISSET(info->myFd,&fdSet)) { if (verbose) ortp_message("stun: received on A1:P1"); recvAltIp = FALSE; recvAltPort = FALSE; ok = getMessage( info->myFd, msg, &msgLen, &from.addr, &from.port,verbose ); } else if (FD_ISSET(info->altPortFd, &fdSet)) { if (verbose) ortp_message("stun: received on A1:P2"); 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) ortp_message("stun: received on A2:P1"); 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) ortp_message("stun: received on A2:P2"); recvAltIp = TRUE; recvAltPort = TRUE; ok = getMessage( info->altIpPortFd, msg, &msgLen, &from.addr, &from.port,verbose ); } else { return TRUE; } if (info->relay) { int i; for (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) { int i; for (i=0; i<MAX_MEDIA_RELAYS; ++i) { StunMediaRelay* relay = &info->relays[i]; if (relay->fd == 0) { if ( verbose ) ortp_message("stun: Open relay port %i\n", relay->relayPort ); 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 ) ortp_message("stun: Get message did not return a valid message\n"); return TRUE; } if ( verbose ) ortp_message("stun: Got a request (len=%i) from %i", msgLen, from.addr); if ( msgLen <= 0 ) { return TRUE; } 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 ) ortp_error("stun: Failed to parse message"); return TRUE; } 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 ); */ Socket sendFd; bool_t sendAltIp = recvAltIp; /* send on the received IP address */ bool_t 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;}#endifint 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,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -