source: branches/oneport/libtransmission/net.c @ 40

Last change on this file since 40 was 40, checked in by joshe, 16 years ago

More random debug stuff, also actually change the port right away via the gtk prefs.

File size: 4.8 KB
Line 
1/******************************************************************************
2 * Copyright (c) 2005 Eric Petit
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 * DEALINGS IN THE SOFTWARE.
21 *****************************************************************************/
22
23#include "transmission.h"
24
25static int makeSocketNonBlocking( int s )
26{
27    int flags;
28
29#ifdef SYS_BEOS
30    flags = 1;
31    if( setsockopt( s, SOL_SOCKET, SO_NONBLOCK,
32                    &flags, sizeof( int ) ) < 0 )
33#else
34    if( ( flags = fcntl( s, F_GETFL, 0 ) ) < 0 ||
35        fcntl( s, F_SETFL, flags | O_NONBLOCK ) < 0 )
36#endif
37    {
38        tr_err( "Could not set socket to non-blocking mode (%s)",
39                strerror( errno ) );
40        tr_netClose( s );
41        return -1;
42    }
43
44    return s;
45}
46
47static int createSocket()
48{
49    int s;
50
51    s = socket( AF_INET, SOCK_STREAM, 0 );
52    if( s < 0 )
53    {
54        tr_err( "Could not create socket (%s)", strerror( errno ) );
55        return -1;
56    }
57
58    return makeSocketNonBlocking( s );
59}
60
61int tr_netResolve( char * address, struct in_addr * addr )
62{
63    struct hostent * host;
64
65    addr->s_addr = inet_addr( address );
66    if( addr->s_addr != 0xFFFFFFFF )
67    {
68        return 0;
69    }
70
71    if( !( host = gethostbyname( address ) ) )
72    {
73        tr_err( "Could not resolve (%s)", address );
74        return -1;
75    }
76    memcpy( addr, host->h_addr, host->h_length );
77
78    return 0;
79}
80
81int tr_netOpen( struct in_addr addr, in_port_t port )
82{
83    int s;
84    struct sockaddr_in sock;
85
86    s = createSocket();
87    if( s < 0 )
88    {
89        return -1;
90    }
91
92    memset( &sock, 0, sizeof( sock ) );
93    sock.sin_family      = AF_INET;
94    sock.sin_addr.s_addr = addr.s_addr;
95    sock.sin_port        = port;
96
97    if( connect( s, (struct sockaddr *) &sock,
98                 sizeof( struct sockaddr_in ) ) < 0 &&
99        errno != EINPROGRESS )
100    {
101        tr_err( "Could not connect socket (%s)", strerror( errno ) );
102        tr_netClose( s );
103        return -1;
104    }
105
106    return s;
107}
108
109int tr_netBind( int port )
110{
111    int s;
112    struct sockaddr_in sock;
113#ifdef SO_REUSEADDR
114    int optval;
115#endif
116
117    s = createSocket();
118    if( s < 0 )
119    {
120        return -1;
121    }
122
123#ifdef SO_REUSEADDR
124    optval = 1;
125    setsockopt( s, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof( optval ) );
126#endif
127
128    memset( &sock, 0, sizeof( sock ) );
129    sock.sin_family      = AF_INET;
130    sock.sin_addr.s_addr = INADDR_ANY;
131    sock.sin_port        = htons( port );
132
133    if( bind( s, (struct sockaddr *) &sock,
134               sizeof( struct sockaddr_in ) ) )
135    {
136        tr_err( "Could not bind port %d: %s", port, strerror(errno) );
137        tr_netClose( s );
138        return -1;
139    }
140   
141    tr_inf( "Binded port %d", port );
142    listen( s, 5 );
143
144    return s;
145}
146
147int tr_netAccept( int s, struct in_addr * addr, in_port_t * port )
148{
149    int t;
150    unsigned len;
151    struct sockaddr_in sock;
152
153    len = sizeof( sock );
154    t   = accept( s, (struct sockaddr *) &sock, &len );
155
156    if( t < 0 )
157    {
158        return -1;
159    }
160   
161    *addr = sock.sin_addr;
162    *port = sock.sin_port;
163
164    return makeSocketNonBlocking( t );
165}
166
167int tr_netSend( int s, uint8_t * buf, int size )
168{
169    int ret;
170
171    ret = send( s, buf, size, 0 );
172    if( ret < 0 )
173    {
174        if( errno == ENOTCONN || errno == EAGAIN || errno == EWOULDBLOCK )
175        {
176            ret = TR_NET_BLOCK;
177        }
178        else
179        {
180            ret = TR_NET_CLOSE;
181        }
182    }
183
184    return ret;
185}
186
187int tr_netRecv( int s, uint8_t * buf, int size )
188{
189    int ret;
190
191    ret = recv( s, buf, size, 0 );
192    if( ret < 0 )
193    {
194        if( errno == EAGAIN || errno == EWOULDBLOCK )
195        {
196            ret = TR_NET_BLOCK;
197        }
198        else
199        {
200            ret = TR_NET_CLOSE;
201        }
202    }
203    if( !ret )
204    {
205        ret = TR_NET_CLOSE;
206    }
207
208    return ret;
209}
210
211void tr_netClose( int s )
212{
213#ifdef BEOS_NETSERVER
214    closesocket( s );
215#else
216    close( s );
217#endif
218}
Note: See TracBrowser for help on using the repository browser.