*** empty log message ***
[chuck-blob.git] / exile / v1 / src / util_network.c
blobc1c04460f4bf877e0d0064bedd509c9d3a609ef4
1 /*----------------------------------------------------------------------------
2 ChucK Concurrent, On-the-fly Audio Programming Language
3 Compiler and Virtual Machine
5 Copyright (c) 2004 Ge Wang and Perry R. Cook. All rights reserved.
6 http://chuck.cs.princeton.edu/
7 http://soundlab.cs.princeton.edu/
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
22 U.S.A.
23 -----------------------------------------------------------------------------*/
25 //-----------------------------------------------------------------------------
26 // name: util_network.c
27 // desc: sockets
28 //
29 // author: Ge Wang (gewang@cs.princeton.edu)
30 // Perry R. Cook (prc@cs.princeton.edu)
32 // originally randy_socket
33 // author: Peng Bi (pbi@cs.princeton.edu)
34 // Ge Wang (gewang@cs.princeton.edu)
35 // date: Winter 2003
36 //-----------------------------------------------------------------------------
37 #include "util_network.h"
38 #include "chuck_utils.h"
39 #include <stdio.h>
41 #if defined(__PLATFORM_WIN32__)
42 #include <winsock.h>
43 #else
44 #include <sys/types.h>
45 #include <sys/socket.h>
46 #include <sys/time.h>
47 #include <unistd.h>
48 #include <netinet/in.h>
49 #include <netinet/tcp.h>
50 #include <arpa/inet.h>
51 #include <netdb.h>
52 #endif
57 #ifdef __PLATFORM_WIN32__
58 static WSADATA g_wsd;
59 static int g_init = 0;
60 #ifndef socklen_t
61 #define socklen_t int
62 #endif
63 #endif
65 //-----------------------------------------------------------------------------
66 // name: struct ck_socket_
67 // desc: ...
68 //-----------------------------------------------------------------------------
69 struct ck_socket_
71 int sock;
72 int prot;
73 struct sockaddr_in sock_in;
74 socklen_t len;
80 //-----------------------------------------------------------------------------
81 // name: ck_udp_create()
82 // desc: create a udp socket
83 //-----------------------------------------------------------------------------
84 ck_socket ck_udp_create( )
86 ck_socket sock = NULL;
88 #ifdef __PLATFORM_WIN32__
89 // winsock init
90 if( g_init == 0 )
91 if( WSAStartup( MAKEWORD(1,1), &(g_wsd) ) != 0 &&
92 WSAStartup( MAKEWORD(1,0), &(g_wsd) ) != 0 )
94 fprintf( stderr, "[chuck]: cannot start winsock, networking disabled...\n" );
95 return NULL;
98 // count
99 g_init++;
100 #endif
102 sock = (ck_socket)checked_malloc( sizeof( struct ck_socket_ ) );
103 sock->sock = socket( AF_INET, SOCK_DGRAM, 0 );
104 sock->prot = SOCK_DGRAM;
106 return sock;
112 //-----------------------------------------------------------------------------
113 // name: ck_tcp_create()
114 // desc: create a tcp socket
115 //-----------------------------------------------------------------------------
116 ck_socket ck_tcp_create( int flags )
118 ck_socket sock = (ck_socket)checked_malloc( sizeof( struct ck_socket_ ) );
119 int nd = 1; int ru = 1;
121 #ifdef __PLATFORM_WIN32__
122 // winsock init
123 if( g_init == 0 )
124 if( WSAStartup( MAKEWORD(1,1), &(g_wsd) ) != 0 &&
125 WSAStartup( MAKEWORD(1,0), &(g_wsd) ) != 0 )
127 fprintf( stderr, "[chuck]: cannot start winsock, networking disabled...\n" );
128 return NULL;
131 // count
132 g_init++;
133 #endif
135 sock->sock = socket( AF_INET, SOCK_STREAM, 0 );
136 sock->prot = SOCK_STREAM;
138 if( flags )
139 setsockopt( sock->sock, SOL_SOCKET, SO_REUSEADDR, (const char *)&ru, sizeof(ru) );
140 // setsockopt( sock->sock, SOL_SOCKET, SO_REUSEPORT, (const char *)&ru, sizeof(ru) );
141 setsockopt( sock->sock, IPPROTO_TCP, TCP_NODELAY, (const char *)&nd, sizeof(nd) );
143 return sock;
149 //-----------------------------------------------------------------------------
150 // name: ck_connect2()
151 // desc: connect to a server
152 //-----------------------------------------------------------------------------
153 t_CKBOOL ck_connect2( ck_socket sock, const struct sockaddr * addr, int size )
155 int ret = connect( sock->sock, addr, size );
157 return ( ret >= 0 );
163 //-----------------------------------------------------------------------------
164 // name: ck_connect()
165 // desc: connect to a server
166 //-----------------------------------------------------------------------------
167 t_CKBOOL ck_connect( ck_socket sock, const char * hostname, int port )
169 int ret;
170 struct hostent * host;
172 #ifdef __PLATFORM_WIN32__
173 memset( &sock->sock_in, 0, sizeof(struct sockaddr_in) );
174 #else
175 bzero( &sock->sock_in, sizeof(struct sockaddr_in) );
176 #endif
178 sock->sock_in.sin_family = AF_INET;
179 sock->sock_in.sin_port = htons( (unsigned short)port );
180 // lookup name
181 host = gethostbyname( hostname );
182 if( !host )
184 sock->sock_in.sin_addr.s_addr = inet_addr( hostname );
185 if( sock->sock_in.sin_addr.s_addr == -1 )
186 return FALSE;
188 else
190 #ifdef __PLATFORM_WIN32__
191 memcpy( (char *)&sock->sock_in.sin_addr, host->h_addr, host->h_length );
192 #else
193 bcopy( host->h_addr, (char *)&sock->sock_in.sin_addr, host->h_length );
194 #endif
197 ret = ck_connect2( sock, (struct sockaddr *)&sock->sock_in,
198 sizeof( struct sockaddr_in ) );
200 return ( ret >= 0 );
206 //-----------------------------------------------------------------------------
207 // name: ck_bind()
208 // desc: bind to a port
209 //-----------------------------------------------------------------------------
210 t_CKBOOL ck_bind( ck_socket sock, int port )
212 int ret;
214 #ifdef __PLATFORM_WIN32__
215 memset( &sock->sock_in, 0, sizeof(struct sockaddr_in) );
216 #else
217 bzero( &sock->sock_in, sizeof(struct sockaddr_in) );
218 #endif
220 sock->sock_in.sin_family = AF_INET;
221 sock->sock_in.sin_port = htons( (unsigned short)port );
222 sock->sock_in.sin_addr.s_addr = htonl( INADDR_ANY );
224 ret = bind( sock->sock, (struct sockaddr *)&sock->sock_in,
225 sizeof(struct sockaddr_in));
227 return ( ret >= 0 );
233 //-----------------------------------------------------------------------------
234 // name: ck_listen()
235 // desc: ...
236 //-----------------------------------------------------------------------------
237 t_CKBOOL ck_listen( ck_socket sock, int backlog )
239 int ret;
241 if( sock->prot != SOCK_STREAM ) return FALSE;
242 ret = listen( sock->sock, backlog );
244 return ( ret >= 0 );
250 //-----------------------------------------------------------------------------
251 // name: ck_accept()
252 // desc: ...
253 //-----------------------------------------------------------------------------
254 ck_socket ck_accept( ck_socket sock )
256 ck_socket client;
257 int nd = 1;
259 if( sock->prot != SOCK_STREAM ) return NULL;
260 client = (ck_socket)checked_malloc( sizeof( struct ck_socket_ ) );
261 client->len = sizeof( client->sock_in );
262 client->sock = accept( sock->sock, (struct sockaddr *)&client->sock_in,
263 &client->len );
264 if( client->sock <= 0 ) goto error;
265 client->prot = SOCK_STREAM;
266 setsockopt( client->sock, IPPROTO_TCP, TCP_NODELAY, (const char *)&nd, sizeof(nd) );
268 #ifdef __PLATFORM_WIN32__
269 g_init++;
270 #endif
272 return client;
274 error:
275 free( client );
276 return NULL;
282 //-----------------------------------------------------------------------------
283 // name: ck_send()
284 // desc: send a datagram
285 //-----------------------------------------------------------------------------
286 int ck_send( ck_socket sock, const char * buffer, int len )
288 return send( sock->sock, buffer, len, 0 );
294 //-----------------------------------------------------------------------------
295 // name: ck_sendto()
296 // desc: send a datagram
297 //-----------------------------------------------------------------------------
298 int ck_sendto( ck_socket sock, const char * buffer, int len,
299 const struct sockaddr * to, int tolen )
301 if( sock->prot == SOCK_STREAM ) return 0;
302 else return sendto( sock->sock, buffer, len, 0, to, tolen );
308 //-----------------------------------------------------------------------------
309 // name: ck_recvfrom()
310 // desc: recv a datagram
311 //-----------------------------------------------------------------------------
312 int ck_recvfrom( ck_socket sock, char * buffer, int len,
313 struct sockaddr * from, int * fromlen )
315 if( sock->prot == SOCK_STREAM )
317 memset( buffer, 0, len );
318 return 0;
320 else return recvfrom( sock->sock, buffer, len, 0, from, (unsigned int *)fromlen );
326 //-----------------------------------------------------------------------------
327 // name: ck_recv()
328 // desc: recv a datagram
329 //-----------------------------------------------------------------------------
330 int ck_recv( ck_socket sock, char * buffer, int len )
332 if( sock->prot == SOCK_STREAM )
334 int ret;
335 int togo = len;
336 char * p = buffer;
337 while( togo > 0 )
339 ret = recv( sock->sock, p, togo, 0 );
340 if( ret < 0 ) return 0;
341 togo -= ret;
342 p += ret;
344 return len;
346 else return recv( sock->sock, buffer, len, 0);
352 //-----------------------------------------------------------------------------
353 // name: ck_send_timeout()
354 // desc: ...
355 //-----------------------------------------------------------------------------
356 int ck_send_timeout( ck_socket sock, long sec, long usec )
358 struct timeval t;
359 t.tv_sec = sec;
360 t.tv_usec = usec;
362 return 0 == setsockopt( sock->sock, SOL_SOCKET, SO_SNDTIMEO, (const char *)&t, sizeof(t) );
368 //-----------------------------------------------------------------------------
369 // name: ck_recv_timeout()
370 // desc: ...
371 //-----------------------------------------------------------------------------
372 int ck_recv_timeout( ck_socket sock, long sec, long usec )
374 struct timeval t;
375 t.tv_sec = sec;
376 t.tv_usec = usec;
378 return 0 == setsockopt( sock->sock, SOL_SOCKET, SO_RCVTIMEO, (const char *)&t, sizeof(t) );
384 //-----------------------------------------------------------------------------
385 // name: ck_close()
386 // close the socket
387 //-----------------------------------------------------------------------------
388 void ck_close( ck_socket sock )
390 if( !sock ) return;
392 #ifdef __PLATFORM_WIN32__
393 closesocket( sock->sock );
394 #else
395 close( sock->sock );
396 #endif
398 free( sock );
400 #ifdef __PLATFORM_WIN32__
401 // uncount
402 g_init--;
404 // close
405 if( g_init == 0 ) WSACleanup();
406 #endif