4 // Copyright (c) 2002 Alan Hawrylyshen, Jason Fischl
6 // Permission is hereby granted, free of charge, to any person obtaining
7 // a copy of this software and associated documentation files (the
8 // "Software"), to deal in the Software without restriction, including
9 // without limitation the rights to use, copy, modify, merge, publish,
10 // distribute, sublicense, and/or sell copies of the Software, and to
11 // permit persons to whom the Software is furnished to do so, subject to
12 // the following conditions:
14 // The above copyright notice and this permission notice shall be
15 // included in all copies or substantial portions of the Software.
17 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21 // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22 // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23 // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 // A portion of this code is taken from lbproxy, a part of VOCAL.
28 // http://www.vovida.org/vocal/
43 #if defined(__GNUC__) && __GNUC__ > 2
60 #include <arpa/inet.h>
64 #include <netinet/in.h>
65 #include <sys/socket.h>
66 #include <sys/types.h>
79 parseHostName( char* peerName
,
81 unsigned short* portVal
,
82 unsigned int defaultPort
)
87 strncpy(host
,peerName
,512);
91 int portNum
= defaultPort
;
93 // pull out the port part if present.
94 char* sep
= strchr(host
,':');
98 portNum
= defaultPort
;
108 portNum
= strtol(port
,&endPtr
,0);
110 if ( endPtr
!= NULL
)
112 if ( *endPtr
!= '\0' )
114 portNum
= defaultPort
;
119 assert( portNum
>= 1024 );
120 assert( portNum
<= 65000 );
124 // figure out the host part
127 h
= gethostbyname( host
);
130 *ip
= ntohl( 0x7F000001L
);
134 sin_addr
= *(struct in_addr
*)h
->h_addr
;
135 *ip
= ntohl( sin_addr
.s_addr
);
143 openPort( unsigned short port
, unsigned int interfaceIp
)
147 fd
= socket(PF_INET
, SOCK_DGRAM
, IPPROTO_UDP
);
148 if ( fd
== INVALID_SOCKET
)
151 //cerr << "Could not create a UDP socket:" << err << endl;
152 return INVALID_SOCKET
;
158 // just use an ephermieal port - no bind
163 struct sockaddr_in addr
;
164 memset((char*) &(addr
),0, sizeof((addr
)));
165 addr
.sin_family
= AF_INET
;
166 addr
.sin_addr
.s_addr
= htonl(INADDR_ANY
);
167 addr
.sin_port
= htons(port
);
169 if ( (interfaceIp
!= 0) &&
170 ( interfaceIp
!= 0x100007f ) )
172 addr
.sin_addr
.s_addr
= htonl(interfaceIp
);
175 if ( bind( fd
,(struct sockaddr
*)&addr
, sizeof(addr
)) != 0 )
183 //cerr << "Port " << port << " for receiving UDP is in use" << endl;
184 return INVALID_SOCKET
;
189 //cerr << "Cannot assign requested address" << endl;
190 return INVALID_SOCKET
;
195 //cerr << "Could not bind UDP receive port. Error=" << e << endl;
196 return INVALID_SOCKET
;
201 //clog << "Opened port " << port << " on fd " << fd << endl;
203 assert( fd
!= INVALID_SOCKET
);
210 getMessage( Socket fd
, char* buf
, int* len
,
211 unsigned int* srcIp
, unsigned short* srcPort
)
213 assert( fd
!= INVALID_SOCKET
);
215 int originalSize
= *len
;
217 struct sockaddr_in from
;
218 #if defined(P_MACOSX) || defined (__BEOS__)
219 int fromLen
= sizeof(from
);
221 socklen_t fromLen
= sizeof(from
);
228 (struct sockaddr
*)&from
,
231 if ( *len
== SOCKET_ERROR
)
238 //cerr << "Error fd not a socket" << endl;
241 ;//cerr << "Error=" << err << endl;
249 //clog << "socket closed?" << endl;
255 //clog << "socket closed?" << endl;
259 *srcPort
= ntohs(from
.sin_port
);
260 *srcIp
= ntohl(from
.sin_addr
.s_addr
);
262 if ( (*len
)+1 >= originalSize
)
264 //cerr << "Received a message that was too large" << endl;
274 sendMessage( Socket fd
, char* buf
, int l
,
275 unsigned int dstIp
, unsigned short dstPort
)
277 assert( fd
!= INVALID_SOCKET
);
282 // sending on a connected port
283 assert( dstIp
== 0 );
285 s
= send(fd
,buf
,l
,0);
289 assert( dstIp
!= 0 );
290 assert( dstPort
!= 0 );
292 struct sockaddr_in to
;
293 int toLen
= sizeof(to
);
296 to
.sin_family
= AF_INET
;
297 to
.sin_port
= htons(dstPort
);
298 to
.sin_addr
.s_addr
= htonl(dstIp
);
300 s
= sendto(fd
, buf
, l
, 0,(sockaddr
*)&to
, toLen
);
303 if ( s
== SOCKET_ERROR
)
316 // quietly ignore this
321 //cerr << "err EAFNOSUPPORT in send" << endl;
326 //cerr << "err " << e << " " << strerror(e) << " in send" << endl;
334 //cerr << "no data sent in send" << endl;
340 //cerr << "only " << s << " out of " << l << " bytes sent" << endl;
352 WORD wVersionRequested
= MAKEWORD( 2, 2 );
356 err
= WSAStartup( wVersionRequested
, &wsaData
);
359 // could not find a usable WinSock DLL
360 //cerr << "Could not load winsock" << endl;
361 assert(0); // is this is failing, try a different version that 2.2, 1.0 or later will likely work
365 /* Confirm that the WinSock DLL supports 2.2.*/
366 /* Note that if the DLL supports versions greater */
367 /* than 2.2 in addition to 2.2, it will still return */
368 /* 2.2 in wVersion since that is the version we */
371 if ( LOBYTE( wsaData
.wVersion
) != 2 ||
372 HIBYTE( wsaData
.wVersion
) != 2 )
374 /* Tell the user that we could not find a usable */
377 //cerr << "Bad winsock verion" << endl;
378 assert(0); // is this is failing, try a different version that 2.2, 1.0 or later will likely work
387 // c-file-style:"ellemtel"
388 // c-file-offsets:((case-label . +))
389 // indent-tabs-mode:nil