#include <cassert>
#include <cstdio>
#include <cstring>
#include <errno.h>
#include <iostream>
#include <cstdlib>
#include <time.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netdb.h>
#include <string.h>
#include "stun_udp.h"
Go to the source code of this file.
Functions | |
Socket | openPort (unsigned short port, unsigned int interfaceIp, bool verbose) |
Open a UDP socket to receive on the given port - if port is 0, pick a a port, if interfaceIp!=0 then use ONLY the interface specified instead of all of them. | |
bool | getMessage (Socket fd, char *buf, int *len, unsigned int *srcIp, unsigned short *srcPort, bool verbose) |
recive a UDP message | |
bool | sendMessage (Socket fd, char *buf, int l, unsigned int dstIp, unsigned short dstPort, bool verbose) |
send a UDP message | |
void | initNetwork () |
set up network - does nothing in unix but needed for windows |
bool getMessage | ( | Socket | fd, | |
char * | buf, | |||
int * | len, | |||
unsigned int * | srcIp, | |||
unsigned short * | srcPort, | |||
bool | verbose | |||
) |
recive a UDP message
Definition at line 114 of file udp.cc.
Referenced by stunNatType(), stunOpenSocket(), stunOpenSocketPair(), stunServerProcess(), and stunTest().
00117 { 00118 assert( fd != STUN_INVALID_SOCKET ); 00119 00120 int originalSize = *len; 00121 assert( originalSize > 0 ); 00122 00123 struct sockaddr_in from; 00124 int fromLen = sizeof(from); 00125 00126 *len = recvfrom(fd, 00127 buf, 00128 originalSize, 00129 0, 00130 (struct sockaddr *)&from, 00131 (socklen_t*)&fromLen); 00132 00133 if ( *len == STUN_SOCKET_ERROR ) 00134 { 00135 int err = getErrno(); 00136 00137 switch (err) 00138 { 00139 case ENOTSOCK: 00140 cerr << "Error fd not a socket" << endl; 00141 break; 00142 case ECONNRESET: 00143 cerr << "Error connection reset - host not reachable" << endl; 00144 break; 00145 00146 default: 00147 cerr << "Socket Error=" << err << endl; 00148 } 00149 00150 return false; 00151 } 00152 00153 if ( *len < 0 ) 00154 { 00155 clog << "socket closed? negative len" << endl; 00156 return false; 00157 } 00158 00159 if ( *len == 0 ) 00160 { 00161 clog << "socket closed? zero len" << endl; 00162 return false; 00163 } 00164 00165 *srcPort = ntohs(from.sin_port); 00166 *srcIp = ntohl(from.sin_addr.s_addr); 00167 00168 if ( (*len)+1 >= originalSize ) 00169 { 00170 if (verbose) 00171 { 00172 clog << "Received a message that was too large" << endl; 00173 } 00174 return false; 00175 } 00176 buf[*len]=0; 00177 00178 return true; 00179 }
void initNetwork | ( | ) |
set up network - does nothing in unix but needed for windows
Definition at line 258 of file udp.cc.
00259 { 00260 #ifdef WIN32 00261 WORD wVersionRequested = MAKEWORD( 2, 2 ); 00262 WSADATA wsaData; 00263 int err; 00264 00265 err = WSAStartup( wVersionRequested, &wsaData ); 00266 if ( err != 0 ) 00267 { 00268 // could not find a usable WinSock DLL 00269 cerr << "Could not load winsock" << endl; 00270 assert(0); // is this is failing, try a different version that 2.2, 1.0 or later will likely work 00271 exit(1); 00272 } 00273 00274 /* Confirm that the WinSock DLL supports 2.2.*/ 00275 /* Note that if the DLL supports versions greater */ 00276 /* than 2.2 in addition to 2.2, it will still return */ 00277 /* 2.2 in wVersion since that is the version we */ 00278 /* requested. */ 00279 00280 if ( LOBYTE( wsaData.wVersion ) != 2 || 00281 HIBYTE( wsaData.wVersion ) != 2 ) 00282 { 00283 /* Tell the user that we could not find a usable */ 00284 /* WinSock DLL. */ 00285 WSACleanup( ); 00286 cerr << "Bad winsock verion" << endl; 00287 assert(0); // is this is failing, try a different version that 2.2, 1.0 or later will likely work 00288 exit(1); 00289 } 00290 #endif 00291 }
Socket openPort | ( | unsigned short | port, | |
unsigned int | interfaceIp, | |||
bool | verbose | |||
) |
Open a UDP socket to receive on the given port - if port is 0, pick a a port, if interfaceIp!=0 then use ONLY the interface specified instead of all of them.
Definition at line 38 of file udp.cc.
Referenced by stunInitServer(), stunNatType(), stunOpenSocket(), stunOpenSocketPair(), stunServerProcess(), and stunTest().
00039 { 00040 Socket fd; 00041 00042 fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); 00043 if ( fd == STUN_INVALID_SOCKET ) 00044 { 00045 int err = getErrno(); 00046 cerr << "Could not create a UDP socket:" << err << endl; 00047 return STUN_INVALID_SOCKET; 00048 } 00049 00050 struct sockaddr_in addr; 00051 memset((char*) &(addr),0, sizeof((addr))); 00052 addr.sin_family = AF_INET; 00053 addr.sin_addr.s_addr = htonl(INADDR_ANY); 00054 addr.sin_port = htons(port); 00055 00056 if ( (interfaceIp != 0) && 00057 ( interfaceIp != 0x100007f ) ) 00058 { 00059 addr.sin_addr.s_addr = htonl(interfaceIp); 00060 if (verbose ) 00061 { 00062 clog << "Binding to interface " 00063 << hex << "0x" << htonl(interfaceIp) << dec << endl; 00064 } 00065 } 00066 00067 if ( bind( fd,(struct sockaddr*)&addr, sizeof(addr)) != 0 ) 00068 { 00069 int e = getErrno(); 00070 00071 switch (e) 00072 { 00073 case 0: 00074 { 00075 cerr << "Could not bind socket" << endl; 00076 return STUN_INVALID_SOCKET; 00077 } 00078 case EADDRINUSE: 00079 { 00080 cerr << "Port " << port << " for receiving UDP is in use" << endl; 00081 return STUN_INVALID_SOCKET; 00082 } 00083 break; 00084 case EADDRNOTAVAIL: 00085 { 00086 if ( verbose ) 00087 { 00088 cerr << "Cannot assign requested address" << endl; 00089 } 00090 return STUN_INVALID_SOCKET; 00091 } 00092 break; 00093 default: 00094 { 00095 cerr << "Could not bind UDP receive port" 00096 << "Error=" << e << " " << strerror(e) << endl; 00097 return STUN_INVALID_SOCKET; 00098 } 00099 break; 00100 } 00101 } 00102 if ( verbose ) 00103 { 00104 clog << "Opened port " << port << " with fd " << fd << endl; 00105 } 00106 00107 assert( fd != STUN_INVALID_SOCKET ); 00108 00109 return fd; 00110 }
bool sendMessage | ( | Socket | fd, | |
char * | buf, | |||
int | l, | |||
unsigned int | dstIp, | |||
unsigned short | dstPort, | |||
bool | verbose | |||
) |
send a UDP message
Definition at line 183 of file udp.cc.
Referenced by stunSendTest(), and stunServerProcess().
00186 { 00187 assert( fd != STUN_INVALID_SOCKET ); 00188 00189 int s; 00190 if ( dstPort == 0 ) 00191 { 00192 // sending on a connected port 00193 assert( dstIp == 0 ); 00194 00195 s = send(fd,buf,l,0); 00196 } 00197 else 00198 { 00199 assert( dstIp != 0 ); 00200 assert( dstPort != 0 ); 00201 00202 struct sockaddr_in to; 00203 int toLen = sizeof(to); 00204 memset(&to,0,toLen); 00205 00206 to.sin_family = AF_INET; 00207 to.sin_port = htons(dstPort); 00208 to.sin_addr.s_addr = htonl(dstIp); 00209 00210 s = sendto(fd, buf, l, 0,(sockaddr*)&to, toLen); 00211 } 00212 00213 if ( s == STUN_SOCKET_ERROR ) 00214 { 00215 int e = getErrno(); 00216 switch (e) 00217 { 00218 case ECONNREFUSED: 00219 case EHOSTDOWN: 00220 case EHOSTUNREACH: 00221 { 00222 // quietly ignore this 00223 } 00224 break; 00225 case EAFNOSUPPORT: 00226 { 00227 cerr << "err EAFNOSUPPORT in send" << endl; 00228 } 00229 break; 00230 default: 00231 { 00232 cerr << "err " << e << " " << strerror(e) << " in send" << endl; 00233 } 00234 } 00235 return false; 00236 } 00237 00238 if ( s == 0 ) 00239 { 00240 cerr << "no data sent in send" << endl; 00241 return false; 00242 } 00243 00244 if ( s != l ) 00245 { 00246 if (verbose) 00247 { 00248 cerr << "only " << s << " out of " << l << " bytes sent" << endl; 00249 } 00250 return false; 00251 } 00252 00253 return true; 00254 }