Mercurial > hg > freeDiameter
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 |