Mercurial > hg > freeDiameter
comparison libfdcore/p_cnx.c @ 706:4ffbc9f1e922
Large UNTESTED commit with the following changes:
* Improved DiameterIdentity handling (esp. interationalization issues),
and improve efficiency of some string operations in peers, sessions,
and dictionary modules (closes #7)
* Cleanup in the session module to free only unreferenced sessions (#16)
* Removed fd_cpu_flush_cache(), replaced by more robust alternatives.
* Improved peer state machine algorithm to counter SCTP multistream race
condition.
author | Sebastien Decugis <sdecugis@nict.go.jp> |
---|---|
date | Wed, 09 Feb 2011 15:26:58 +0900 |
parents | 78b665400097 |
children | 4a9f08d6b6ba |
comparison
equal
deleted
inserted
replaced
705:f0cb8f465763 | 706:4ffbc9f1e922 |
---|---|
33 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * | 33 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * |
34 *********************************************************************************************************/ | 34 *********************************************************************************************************/ |
35 | 35 |
36 #include "fdcore-internal.h" | 36 #include "fdcore-internal.h" |
37 | 37 |
38 | |
39 /* TODO: change the behavior to handle properly forced ordering at beginning & end of OPEN state */ | |
40 | |
38 /* This file contains code used by a peer state machine to initiate a connection to remote peer */ | 41 /* This file contains code used by a peer state machine to initiate a connection to remote peer */ |
39 | 42 |
40 struct next_conn { | 43 struct next_conn { |
41 struct fd_list chain; | 44 struct fd_list chain; |
42 int proto; /* Protocol of the next attempt */ | 45 int proto; /* Protocol of the next attempt */ |
84 | 87 |
85 memset(&hints, 0, sizeof(hints)); | 88 memset(&hints, 0, sizeof(hints)); |
86 hints.ai_flags = AI_ADDRCONFIG; | 89 hints.ai_flags = AI_ADDRCONFIG; |
87 ret = getaddrinfo(peer->p_hdr.info.pi_diamid, NULL, &hints, &ai); | 90 ret = getaddrinfo(peer->p_hdr.info.pi_diamid, NULL, &hints, &ai); |
88 if (ret) { | 91 if (ret) { |
89 fd_log_debug("Unable to resolve address for peer '%s' (%s), aborting\n", peer->p_hdr.info.pi_diamid, gai_strerror(ret)); | 92 TRACE_DEBUG(INFO, "Unable to resolve address for peer '%s' (%s), aborting\n", peer->p_hdr.info.pi_diamid, gai_strerror(ret)); |
90 if (ret != EAI_AGAIN) | 93 if (ret != EAI_AGAIN) |
91 fd_psm_terminate( peer, NULL ); | 94 fd_psm_terminate( peer, NULL ); |
92 return 0; | 95 return 0; |
93 } | 96 } |
94 | 97 |
120 /* Remove any local address that would be here, it should not happen but it does sometimes... */ | 123 /* Remove any local address that would be here, it should not happen but it does sometimes... */ |
121 CHECK_FCT( fd_ep_filter_list(&peer->p_hdr.info.pi_endpoints, &fd_g_config->cnf_endpoints) ); | 124 CHECK_FCT( fd_ep_filter_list(&peer->p_hdr.info.pi_endpoints, &fd_g_config->cnf_endpoints) ); |
122 | 125 |
123 /* Now check we have at least one address to attempt */ | 126 /* Now check we have at least one address to attempt */ |
124 if (FD_IS_LIST_EMPTY(&peer->p_hdr.info.pi_endpoints)) { | 127 if (FD_IS_LIST_EMPTY(&peer->p_hdr.info.pi_endpoints)) { |
125 fd_log_debug("No address %savailable to connect to peer '%s', aborting\n", peer->p_hdr.info.config.pic_flags.pro3 ? "in the configured family " : "", peer->p_hdr.info.pi_diamid); | 128 TRACE_DEBUG(INFO, "No address %savailable to connect to peer '%s', aborting\n", |
129 peer->p_hdr.info.config.pic_flags.pro3 ? "in the configured family " : "", peer->p_hdr.info.pi_diamid); | |
126 fd_psm_terminate( peer, NULL ); | 130 fd_psm_terminate( peer, NULL ); |
127 return 0; | 131 return 0; |
128 } | 132 } |
129 | 133 |
130 /* Cleanup any previous list */ | 134 /* Cleanup any previous list */ |
216 CHECK_PARAMS_DO( CHECK_PEER(peer), return NULL ); | 220 CHECK_PARAMS_DO( CHECK_PEER(peer), return NULL ); |
217 | 221 |
218 /* Set the thread name */ | 222 /* Set the thread name */ |
219 { | 223 { |
220 char buf[48]; | 224 char buf[48]; |
221 sprintf(buf, "ConnTo:%.*s", (int)(sizeof(buf)) - 8, peer->p_hdr.info.pi_diamid); | 225 snprintf(buf, sizeof(buf), "ConnTo:%s", peer->p_hdr.info.pi_diamid); |
222 fd_log_threadname ( buf ); | 226 fd_log_threadname ( buf ); |
223 } | 227 } |
224 | 228 |
225 do { | 229 do { |
226 /* Rebuild the list if needed, if it is empty -- but at most once */ | 230 /* Rebuild the list if needed, if it is empty -- but at most once */ |
244 case IPPROTO_TCP: | 248 case IPPROTO_TCP: |
245 cnx = fd_cnx_cli_connect_tcp((sSA *)&nc->ss, sSAlen(&nc->ss)); | 249 cnx = fd_cnx_cli_connect_tcp((sSA *)&nc->ss, sSAlen(&nc->ss)); |
246 break; | 250 break; |
247 #ifndef DISABLE_SCTP | 251 #ifndef DISABLE_SCTP |
248 case IPPROTO_SCTP: | 252 case IPPROTO_SCTP: |
249 cnx = fd_cnx_cli_connect_sctp((peer->p_hdr.info.config.pic_flags.pro3 == PI_P3_IP) ?: fd_g_config->cnf_flags.no_ip6, nc->port, &peer->p_hdr.info.pi_endpoints); | 253 cnx = fd_cnx_cli_connect_sctp((peer->p_hdr.info.config.pic_flags.pro3 == PI_P3_IP) ?: fd_g_config->cnf_flags.no_ip6, |
254 nc->port, &peer->p_hdr.info.pi_endpoints); | |
250 break; | 255 break; |
251 #endif /* DISABLE_SCTP */ | 256 #endif /* DISABLE_SCTP */ |
252 } | 257 } |
253 | 258 |
254 if (cnx) | 259 if (cnx) |
257 /* Pop these parameters and continue */ | 262 /* Pop these parameters and continue */ |
258 failed_connection_attempt(peer); | 263 failed_connection_attempt(peer); |
259 | 264 |
260 pthread_testcancel(); | 265 pthread_testcancel(); |
261 | 266 |
262 } while (!cnx); /* and until cancellation */ | 267 } while (!cnx); /* and until cancellation or all addresses attempted without success */ |
263 | 268 |
264 /* Now, we have an established connection in cnx */ | 269 /* Now, we have an established connection in cnx */ |
265 | 270 |
266 pthread_cleanup_push((void *)fd_cnx_destroy, cnx); | 271 pthread_cleanup_push((void *)fd_cnx_destroy, cnx); |
267 | 272 |
271 /* Handshake if needed (secure port) */ | 276 /* Handshake if needed (secure port) */ |
272 if (nc->dotls) { | 277 if (nc->dotls) { |
273 CHECK_FCT_DO( fd_cnx_handshake(cnx, GNUTLS_CLIENT, peer->p_hdr.info.config.pic_priority, NULL), | 278 CHECK_FCT_DO( fd_cnx_handshake(cnx, GNUTLS_CLIENT, peer->p_hdr.info.config.pic_priority, NULL), |
274 { | 279 { |
275 /* Handshake failed ... */ | 280 /* Handshake failed ... */ |
276 fd_log_debug("TLS Handshake failed with peer '%s', resetting the connection\n", peer->p_hdr.info.pi_diamid); | 281 TRACE_DEBUG(INFO, "TLS Handshake failed with peer '%s', resetting the connection\n", peer->p_hdr.info.pi_diamid); |
277 fd_cnx_destroy(cnx); | 282 fd_cnx_destroy(cnx); |
278 empty_connection_list(peer); | 283 empty_connection_list(peer); |
279 fd_ep_filter(&peer->p_hdr.info.pi_endpoints, EP_FL_CONF); | 284 fd_ep_filter(&peer->p_hdr.info.pi_endpoints, EP_FL_CONF); |
280 goto out_pop; | 285 goto out_pop; |
281 } ); | 286 } ); |