comparison libfdcore/tcp.c @ 658:f198d16fa7f4

Initial commit for 1.1.0: * Restructuring: * libfreeDiameter: - renamed folder & binary into libfdproto - renamed libfD.h into fdproto-internal.h - removed signals management (replaced by triggers in libfdcore) * freeDiameter split into: - libfdcore (most contents) - renamed fD.h into fdcore-internal.h - added core.c for framework init/shutdown. - new triggers mechanism in events.c. - freeDiameterd (main, command line parsing, signals management) * tests: - now in top-level directory tests. * other changes: - fd_dict_new now returns 0 on duplicate identical entries. - fixes in dict_legacy_xml - fixes in some dictionaries - moved FD_DEFAULT_CONF_FILENAME definition to freeDiameter-host.h
author Sebastien Decugis <sdecugis@nict.go.jp>
date Fri, 14 Jan 2011 15:15:23 +0900
parents freeDiameter/tcp.c@41e3c2a3721c
children 2e94ef0515d7
comparison
equal deleted inserted replaced
656:5b05d85682f1 658:f198d16fa7f4
1 /*********************************************************************************************************
2 * Software License Agreement (BSD License) *
3 * Author: Sebastien Decugis <sdecugis@nict.go.jp> *
4 * *
5 * Copyright (c) 2010, WIDE Project and NICT *
6 * All rights reserved. *
7 * *
8 * Redistribution and use of this software in source and binary forms, with or without modification, are *
9 * permitted provided that the following conditions are met: *
10 * *
11 * * Redistributions of source code must retain the above *
12 * copyright notice, this list of conditions and the *
13 * following disclaimer. *
14 * *
15 * * Redistributions in binary form must reproduce the above *
16 * copyright notice, this list of conditions and the *
17 * following disclaimer in the documentation and/or other *
18 * materials provided with the distribution. *
19 * *
20 * * Neither the name of the WIDE Project or NICT nor the *
21 * names of its contributors may be used to endorse or *
22 * promote products derived from this software without *
23 * specific prior written permission of WIDE Project and *
24 * NICT. *
25 * *
26 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED *
27 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
28 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR *
29 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *
30 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS *
31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR *
32 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF *
33 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
34 *********************************************************************************************************/
35
36 #include "fdcore-internal.h"
37 #include "cnxctx.h"
38
39 #include <netinet/tcp.h>
40 #include <netinet/ip6.h>
41 #include <sys/socket.h>
42
43 /* Set the socket options for TCP sockets, before bind is called */
44 static int fd_tcp_setsockopt(int family, int sk)
45 {
46 int ret = 0;
47 int opt;
48
49 /* Clear the NODELAY option in case it was set, as requested by rfc3539#section-3.2 */
50 /* Note that this is supposed to be the default, so we could probably remove this call ... */
51 opt = 0;
52 ret = setsockopt(sk, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt));
53 if (ret != 0) {
54 ret = errno;
55 TRACE_DEBUG(INFO, "Unable to set the socket TCP_NODELAY option: %s", strerror(ret));
56 return ret;
57 }
58
59 /* Under Linux, we may also set the TCP_CONGESTION option to one of the following strings:
60 - reno (default)
61 - bic
62 - cubic
63 - highspeed
64 - htcp
65 - hybla
66 - illinois
67 - lp
68 - scalable
69 - vegas
70 - veno
71 - westwood
72 - yeah
73 */
74
75 /* In case of v6 address, force the v6only option, we use a different socket for v4 */
76 #ifdef IPV6_V6ONLY
77 if (family == AF_INET6) {
78 opt = 1;
79 CHECK_SYS(setsockopt(sk, IPPROTO_IPV6, IPV6_V6ONLY, &opt, sizeof(opt)));
80 }
81 #endif /* IPV6_V6ONLY */
82
83 #ifdef DEBUG
84 {
85 opt = 1;
86 CHECK_SYS( setsockopt(sk, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) );
87 }
88 #endif /* DEBUG */
89
90
91 /* There are also others sockopt that can be set, but nothing useful for us AFAICT */
92
93 return 0;
94 }
95
96 /* Create a socket server and bind it */
97 int fd_tcp_create_bind_server( int * sock, sSA * sa, socklen_t salen )
98 {
99 TRACE_ENTRY("%p %p %d", sock, sa, salen);
100
101 CHECK_PARAMS( sock && sa );
102
103 /* Create the socket */
104 CHECK_SYS( *sock = socket(sa->sa_family, SOCK_STREAM, IPPROTO_TCP) );
105
106 /* Set the socket options */
107 CHECK_FCT( fd_tcp_setsockopt(sa->sa_family, *sock) );
108
109 /* Bind the socket */
110 CHECK_SYS( bind( *sock, sa, salen ) );
111
112 /* We're done */
113 return 0;
114 }
115
116 /* Allow clients connections on server sockets */
117 int fd_tcp_listen( int sock )
118 {
119 TRACE_ENTRY("%d", sock);
120 CHECK_SYS( listen(sock, 5) );
121 return 0;
122 }
123
124 /* Create a client socket and connect to remote server */
125 int fd_tcp_client( int *sock, sSA * sa, socklen_t salen )
126 {
127 int ret = 0;
128 int s;
129
130 TRACE_ENTRY("%p %p %d", sock, sa, salen);
131 CHECK_PARAMS( sock && (*sock <= 0) && sa && salen );
132
133 /* Create the socket */
134 CHECK_SYS( s = socket(sa->sa_family, SOCK_STREAM, IPPROTO_TCP) );
135
136 /* Cleanup if we are cancelled */
137 pthread_cleanup_push(fd_cleanup_socket, &s);
138
139 /* Set the socket options */
140 CHECK_FCT( fd_tcp_setsockopt(sa->sa_family, s) );
141
142 TRACE_DEBUG_sSA(FULL, "Attempting TCP connection with peer: ", sa, NI_NUMERICHOST | NI_NUMERICSERV, "..." );
143
144 /* Try connecting to the remote address */
145 ret = connect(s, sa, salen);
146
147 pthread_cleanup_pop(0);
148
149 if (ret < 0) {
150 int lvl;
151 switch (ret = errno) {
152 case ECONNREFUSED:
153
154 /* "Normal" errors */
155 lvl = FULL;
156 break;
157 default:
158 lvl = INFO;
159 }
160 /* Some errors are expected, we log at different level */
161 TRACE_DEBUG( lvl, "connect returned an error: %s", strerror(ret));
162 CHECK_SYS_DO( close(s), /* continue */ );
163 *sock = -1;
164 return ret;
165 }
166
167 /* Done! */
168 *sock = s;
169 return ret;
170 }
171
172 /* Get the remote name of a TCP socket */
173 int fd_tcp_get_remote_ep(int sock, sSS * ss, socklen_t *sl)
174 {
175 TRACE_ENTRY("%d %p %p", sock, ss, sl);
176 CHECK_PARAMS( ss && sl );
177
178 *sl = sizeof(sSS);
179 CHECK_SYS(getpeername(sock, (sSA *)ss, sl));
180
181 return 0;
182 }
183
"Welcome to our mercurial repository"