Changeset 22:0b3b46da2c12 in freeDiameter
- Timestamp:
- Oct 19, 2009, 6:43:09 PM (14 years ago)
- Branch:
- default
- Phase:
- public
- Files:
-
- 1 added
- 15 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/freediameter.conf.sample
r21 r22 184 184 # No_TLS; # assume transparent security instead of TLS 185 185 # Port = 3868; # The port to connect to 186 # SCTP_streams = 30;187 186 # TcTimer = 30; 188 187 # TwTimer = 30; 189 188 # ConnectTo = "202.249.37.5"; 190 189 # ConnectTo = "2001:200:903:2::202:1"; 190 # TLS_Prio = "NORMAL"; 191 191 # Examples: 192 192 #ConnectPeer = "aaa.wide.ad.jp"; … … 201 201 SecPort = 3867; 202 202 TLS_old_method; 203 No_ IP;203 No_SCTP; 204 204 Prefer_TCP; 205 205 SCTP_streams = 50; 206 ListenOn = "202.249.37.5";207 ListenOn = "2001:200:903:2::202:1";206 #ListenOn = "202.249.37.5"; 207 #ListenOn = "2001:200:903:2::202:1"; 208 208 TcTimer = 60; 209 209 TwTimer = 6; … … 213 213 LoadExtension = "extensions/dict_eap.fdx"; 214 214 ConnectPeer = "jules.nautilus6.org" ; 215 ConnectPeer = "aaa.nautilus6.org" { No_TLS; No_IP; No_TCP; SCTP_streams = 60;} ;215 ConnectPeer = "aaa.nautilus6.org" { No_TLS; No_IP; } ; 216 216 TLS_Cred = "/etc/openssl-ca/clients/certs/test.cert" , "/etc/openssl-ca/clients/privkeys/test.key.pem"; 217 217 TLS_CA = "/etc/openssl-ca/public-www/cacert.pem"; -
freeDiameter/CMakeLists.txt
r20 r22 21 21 p_psm.c 22 22 server.c 23 tcp.c 23 24 ) 24 25 -
freeDiameter/cnxctx.c
r21 r22 36 36 #include "fD.h" 37 37 38 /* Connections contexts (cnxctx) in freeDiameter are wrappers around the sockets and TLS operations . 39 * They are used to hide the details of the processing to the higher layers of the daemon. 40 * They are always oriented on connections (TCP or SCTP), connectionless modes (UDP or SCTP) are not supported. 41 */ 42 43 /* Note: this file could be moved to libfreeDiameter instead, but since it uses gnuTLS we prefer to keep it in the daemon */ 44 45 /* Lifetime of a cnxctx object: 46 * 1) Creation 47 * a) a server socket: 48 * - create the object with fd_cnx_serv_tcp or fd_cnx_serv_sctp 49 * - start listening incoming connections: fd_cnx_serv_listen 50 * - accept new clients with fd_cnx_serv_accept. 51 * b) a client socket: 52 * - connect to a remote server with fd_cnx_cli_connect 53 * 54 * 2) Initialization 55 * - if TLS is started first, call fd_cnx_handshake 56 * - otherwise to receive clear messages, call fd_cnx_start_clear. fd_cnx_handshake can be called later. 57 * 58 * 3) Usage 59 * - fd_cnx_receive, fd_cnx_send : exchange messages on this connection (send is synchronous, receive is not). 60 * - fd_cnx_recv_setaltfifo : when a message is received, the event is sent to an external fifo list. fd_cnx_receive does not work when the alt_fifo is set. 61 * - fd_cnx_getid : retrieve a descriptive string for the connection (for debug) 62 * - fd_cnx_getremoteid : identification of the remote peer (IP address or fqdn) 63 * - fd_cnx_getcred : get the remote peer TLS credentials, after handshake 64 * - fd_cnx_getendpoints : get the endpoints (IP) of the connection 65 * 66 * 4) End 67 * - fd_cnx_destroy 68 */ 69 38 70 /* The connection context structure */ 39 71 struct cnxctx { 72 char cc_id[60]; /* The name of this connection */ 73 char cc_remid[60]; /* Id of remote peer */ 74 40 75 int cc_socket; /* The socket object of the connection -- <=0 if no socket is created */ 41 76 42 77 int cc_proto; /* IPPROTO_TCP or IPPROTO_SCTP */ 43 78 int cc_tls; /* Is TLS already started ? */ 44 79 45 80 struct fifo * cc_events; /* Events occuring on the connection */ 46 81 pthread_t cc_mgr; /* manager thread for the connection */ 47 82 struct fifo * cc_incoming; /* FIFO queue of messages received on the connection */ 48 49 uint16_t cc_port; /* Remote port of the connection, when we are client */ 50 struct fd_list cc_ep_remote; /* The remote address(es) of the connection */ 51 struct fd_list cc_ep_local; /* The local address(es) of the connection */ 52 83 struct fifo * cc_alt; /* alternate fifo to send FDEVP_CNX_MSG_RECV events to. */ 84 53 85 /* If cc_proto == SCTP */ 54 86 struct { … … 58 90 int next; /* # of stream the next message will be sent to */ 59 91 } cc_sctp_para; 60 92 61 93 /* If cc_tls == true */ 62 94 struct { … … 64 96 gnutls_session_t session; /* Session object (stream #0 in case of SCTP) */ 65 97 } cc_tls_para; 66 98 67 99 /* If both conditions */ 68 100 struct { … … 73 105 74 106 75 /* Initialize a context structure from a socket*/76 st ruct cnxctx * fd_cnx_init(int sock, int proto)107 /* Initialize a context structure */ 108 static struct cnxctx * fd_cnx_init(int full) 77 109 { 78 110 struct cnxctx * conn = NULL; 79 80 TRACE_ENTRY("%d %d", sock, proto); 81 CHECK_PARAMS_DO( (proto == IPPROTO_TCP) || (proto == IPPROTO_SCTP), return NULL); 82 111 112 TRACE_ENTRY("%d", full); 113 83 114 CHECK_MALLOC_DO( conn = malloc(sizeof(struct cnxctx)), return NULL ); 84 115 memset(conn, 0, sizeof(struct cnxctx)); 85 86 conn->cc_socket = sock; 87 conn->cc_proto = proto; 88 89 fd_list_init(&conn->cc_ep_remote, conn); 90 fd_list_init(&conn->cc_ep_local, conn); 91 92 if (proto == IPPROTO_SCTP) { 116 117 if (full) { 118 CHECK_FCT_DO( fd_fifo_new ( &conn->cc_events ), return NULL ); 119 CHECK_FCT_DO( fd_fifo_new ( &conn->cc_incoming ), return NULL ); 120 } 121 122 return conn; 123 } 124 125 /* Create and bind a server socket to the given endpoint and port */ 126 struct cnxctx * fd_cnx_serv_tcp(uint16_t port, int family, struct fd_endpoint * ep) 127 { 128 struct cnxctx * cnx = NULL; 129 sSS dummy; 130 sSA * sa = (sSA *) &dummy; 131 132 TRACE_ENTRY("%hu %d %p", port, family, ep); 133 134 CHECK_PARAMS_DO( port, return NULL ); 135 CHECK_PARAMS_DO( ep || family, return NULL ); 136 CHECK_PARAMS_DO( (! family) || (family == AF_INET) || (family == AF_INET6), return NULL ); 137 CHECK_PARAMS_DO( (! ep) || (!family) || (ep->ss.ss_family == family), return NULL ); 138 139 /* The connection object */ 140 CHECK_MALLOC_DO( cnx = fd_cnx_init(0), return NULL ); 141 142 /* Prepare the socket address information */ 143 if (ep) { 144 memcpy(sa, &ep->ss, sizeof(sSS)); 145 } else { 146 memset(&dummy, 0, sizeof(dummy)); 147 sa->sa_family = family; 148 } 149 if (sa->sa_family == AF_INET) { 150 ((sSA4 *)sa)->sin_port = htons(port); 151 } else { 152 ((sSA6 *)sa)->sin6_port = htons(port); 153 } 154 155 /* Create the socket */ 156 CHECK_FCT_DO( fd_tcp_create_bind_server( &cnx->cc_socket, sa, sizeof(sSS) ), goto error ); 157 158 /* Generate the name for the connection object */ 159 { 160 char addrbuf[INET6_ADDRSTRLEN]; 161 int rc; 162 rc = getnameinfo(sa, sizeof(sSS), addrbuf, sizeof(addrbuf), NULL, 0, NI_NUMERICHOST); 163 if (rc) 164 snprintf(addrbuf, sizeof(addrbuf), "[err:%s]", gai_strerror(rc)); 165 snprintf(cnx->cc_id, sizeof(cnx->cc_id), "Srv TCP [%s]:%hu (%d)", addrbuf, port, cnx->cc_socket); 166 } 167 168 cnx->cc_proto = IPPROTO_TCP; 169 170 return cnx; 171 172 error: 173 fd_cnx_destroy(cnx); 174 return NULL; 175 } 93 176 #ifndef DISABLE_SCTP 94 CHECK_FCT_DO( fd_sctp_get_str_info( sock, &conn->cc_sctp_para.str_in, &conn->cc_sctp_para.str_out ), 95 { free(conn); return NULL; } ); 96 conn->cc_sctp_para.pairs = (conn->cc_sctp_para.str_out < conn->cc_sctp_para.str_in) ? conn->cc_sctp_para.str_out : conn->cc_sctp_para.str_in; 97 #else /* DISABLE_SCTP */ 98 ASSERT(0); 177 struct cnxctx * fd_cnx_serv_sctp(uint16_t port, struct fd_list * ep_list) 178 { 179 struct cnxctx * cnx = NULL; 180 sSS dummy; 181 sSA * sa = (sSA *) &dummy; 182 183 TRACE_ENTRY("%hu %p", port, ep_list); 184 185 CHECK_PARAMS_DO( port, return NULL ); 186 187 /* The connection object */ 188 CHECK_MALLOC_DO( cnx = fd_cnx_init(0), return NULL ); 189 190 /* Create the socket */ 191 CHECK_FCT_DO( fd_sctp_create_bind_server( &cnx->cc_socket, ep_list, port ), goto error ); 192 193 /* Generate the name for the connection object */ 194 snprintf(cnx->cc_id, sizeof(cnx->cc_id), "Srv SCTP :%hu (%d)", port, cnx->cc_socket); 195 196 cnx->cc_proto = IPPROTO_SCTP; 197 198 return cnx; 199 200 error: 201 fd_cnx_destroy(cnx); 202 return NULL; 203 } 99 204 #endif /* DISABLE_SCTP */ 100 } 101 102 return conn; 205 206 /* Allow clients to connect on the server socket */ 207 int fd_cnx_serv_listen(struct cnxctx * conn) 208 { 209 CHECK_PARAMS( conn ); 210 211 switch (conn->cc_proto) { 212 case IPPROTO_TCP: 213 CHECK_FCT(fd_tcp_listen(conn->cc_socket)); 214 break; 215 216 case IPPROTO_SCTP: 217 CHECK_FCT(fd_sctp_listen(conn->cc_socket)); 218 break; 219 220 default: 221 CHECK_PARAMS(0); 222 } 223 224 return 0; 225 } 226 227 /* Accept a client (blocking until a new client connects) -- cancelable */ 228 struct cnxctx * fd_cnx_serv_accept(struct cnxctx * serv) 229 { 230 struct cnxctx * cli = NULL; 231 sSS ss; 232 socklen_t ss_len = sizeof(ss); 233 int cli_sock = 0; 234 struct fd_endpoint * ep; 235 236 TRACE_ENTRY("%p", serv); 237 CHECK_PARAMS_DO(serv, return NULL); 238 239 CHECK_SYS_DO( cli_sock = accept(serv->cc_socket, (sSA *)&ss, &ss_len), return NULL ); 240 241 if (TRACE_BOOL(INFO)) { 242 fd_log_debug("%s - new client [", fd_cnx_getid(serv)); 243 sSA_DUMP_NODE( &ss, AI_NUMERICHOST ); 244 fd_log_debug("] connected.\n"); 245 } 246 247 CHECK_MALLOC_DO( cli = fd_cnx_init(1), { shutdown(cli_sock, SHUT_RDWR); return NULL; } ); 248 cli->cc_socket = cli_sock; 249 cli->cc_proto = serv->cc_proto; 250 251 /* Generate the name for the connection object */ 252 { 253 char addrbuf[INET6_ADDRSTRLEN]; 254 char portbuf[10]; 255 int rc; 256 257 /* Numeric values for debug */ 258 rc = getnameinfo((sSA *)&ss, sizeof(sSS), addrbuf, sizeof(addrbuf), portbuf, sizeof(portbuf), NI_NUMERICHOST | NI_NUMERICSERV); 259 if (rc) 260 snprintf(addrbuf, sizeof(addrbuf), "[err:%s]", gai_strerror(rc)); 261 262 snprintf(cli->cc_id, sizeof(cli->cc_id), "Client %s [%s]:%s (%d) / serv (%d)", 263 IPPROTO_NAME(cli->cc_proto), 264 addrbuf, portbuf, 265 cli->cc_socket, serv->cc_socket); 266 267 /* Textual value for log messages */ 268 rc = getnameinfo((sSA *)&ss, sizeof(sSS), cli->cc_remid, sizeof(cli->cc_remid), NULL, 0, NI_NUMERICHOST); 269 if (rc) 270 snprintf(cli->cc_remid, sizeof(cli->cc_remid), "[err:%s]", gai_strerror(rc)); 271 } 272 273 /* SCTP-specific handlings */ 274 #ifndef DISABLE_SCTP 275 if (cli->cc_proto == IPPROTO_SCTP) { 276 /* Retrieve the number of streams */ 277 CHECK_FCT_DO( fd_sctp_get_str_info( cli->cc_socket, &cli->cc_sctp_para.str_in, &cli->cc_sctp_para.str_out ), goto error ); 278 if (cli->cc_sctp_para.str_out > cli->cc_sctp_para.str_in) 279 cli->cc_sctp_para.pairs = cli->cc_sctp_para.str_out; 280 else 281 cli->cc_sctp_para.pairs = cli->cc_sctp_para.str_in; 282 } 283 #endif /* DISABLE_SCTP */ 284 285 return cli; 286 error: 287 fd_cnx_destroy(cli); 288 return NULL; 289 } 290 291 /* Client side: connect to a remote server */ 292 struct cnxctx * fd_cnx_cli_connect(int proto, const sSA * sa, socklen_t addrlen) 293 { 294 295 TODO("..."); 296 return NULL; 297 } 298 299 /* Return a string describing the connection, for debug */ 300 char * fd_cnx_getid(struct cnxctx * conn) 301 { 302 CHECK_PARAMS_DO( conn, return "" ); 303 return conn->cc_id; 103 304 } 104 305 … … 106 307 int fd_cnx_start_clear(struct cnxctx * conn) 107 308 { 108 309 109 310 TODO("..."); 110 311 return ENOTSUP; … … 112 313 113 314 /* TLS handshake a connection; no need to have called start_clear before. Reception is active if handhsake is successful */ 114 int fd_cnx_handshake(struct cnxctx * conn, int mode )315 int fd_cnx_handshake(struct cnxctx * conn, int mode, char * priority) 115 316 { 116 317 TRACE_ENTRY( "%p %d", conn, mode); 117 318 CHECK_PARAMS( conn && ( (mode == GNUTLS_CLIENT) || (mode == GNUTLS_SERVER) ) ); 118 319 119 320 /* Save the mode */ 120 321 conn->cc_tls_para.mode = mode; 121 322 122 323 /* Create the master session context */ 123 324 CHECK_GNUTLS_DO( gnutls_init (&conn->cc_tls_para.session, mode), return ENOMEM ); 124 325 125 326 /* Set the algorithm suite */ 327 TODO("Use overwrite priority if non NULL"); 126 328 CHECK_GNUTLS_DO( gnutls_priority_set( conn->cc_tls_para.session, fd_g_config->cnf_sec_data.prio_cache ), return EINVAL ); 127 329 128 330 /* Set the credentials of this side of the connection */ 129 331 CHECK_GNUTLS_DO( gnutls_credentials_set (conn->cc_tls_para.session, GNUTLS_CRD_CERTIFICATE, fd_g_config->cnf_sec_data.credentials), return EINVAL ); 130 332 131 333 /* Request the remote credentials as well */ 132 334 if (mode == GNUTLS_SERVER) { … … 146 348 #endif /* DISABLE_SCTP */ 147 349 } 148 350 149 351 /* Handshake master session */ 150 352 { … … 153 355 { 154 356 if (TRACE_BOOL(INFO)) { 155 fd_log_debug("TLS Handshake failed on socket %d : %s\n", conn->cc_socket, gnutls_strerror(ret));357 fd_log_debug("TLS Handshake failed on socket %d (%s) : %s\n", conn->cc_socket, conn->cc_id, gnutls_strerror(ret)); 156 358 } 157 359 return EINVAL; 158 360 } ); 159 361 160 362 /* Now verify the remote credentials are valid -- only simple test here */ 161 363 CHECK_GNUTLS_DO( gnutls_certificate_verify_peers2 (conn->cc_tls_para.session, &ret), return EINVAL ); 162 364 if (ret) { 163 365 if (TRACE_BOOL(INFO)) { 164 fd_log_debug("TLS: Remote certificate invalid on socket %d :\n", conn->cc_socket);366 fd_log_debug("TLS: Remote certificate invalid on socket %d (%s) :\n", conn->cc_socket, conn->cc_id); 165 367 if (ret & GNUTLS_CERT_INVALID) 166 368 fd_log_debug(" - The certificate is not trusted (unknown CA?)\n"); … … 177 379 } 178 380 } 179 381 180 382 /* Other sessions in case of multi-stream SCTP are resumed from the master */ 181 383 if ((conn->cc_proto == IPPROTO_SCTP) && (conn->cc_sctp_para.pairs > 0)) { … … 184 386 #endif /* DISABLE_SCTP */ 185 387 } 186 388 389 TODO("Start the connection state machine thread"); 390 187 391 return 0; 188 392 } … … 191 395 int fd_cnx_getcred(struct cnxctx * conn, const gnutls_datum_t **cert_list, unsigned int *cert_list_size) 192 396 { 193 397 194 398 TODO("..."); 195 399 return ENOTSUP; 196 400 } 197 401 198 /* Get the list of endpoints (IP addresses) of the remote peer on this object */ 199 int fd_cnx_getendpoints(struct cnxctx * conn, struct fd_list * senti) 200 { 201 402 /* Get the list of endpoints (IP addresses) of the local and remote peers on this conenction */ 403 int fd_cnx_getendpoints(struct cnxctx * conn, struct fd_list * local, struct fd_list * remote) 404 { 405 TRACE_ENTRY("%p %p %p", conn, local, remote); 406 CHECK_PARAMS(conn); 407 408 if (local) { 409 /* Retrieve the local endpoint(s) of the connection */ 410 TODO("TCP : getsockname"); 411 TODO("SCTP: sctp_getladdrs / _sctp_getboundaddrs (waaad)"); 412 } 413 414 if (remote) { 415 /* Retrieve the peer endpoint(s) of the connection */ 416 TODO("TCP : getpeername"); 417 TODO("SCTP: sctp_getpaddrs"); 418 419 } 420 421 return ENOTSUP; 422 } 423 424 425 /* Get a string describing the remote peer address (ip address or fqdn) */ 426 char * fd_cnx_getremoteid(struct cnxctx * conn) 427 { 428 CHECK_PARAMS_DO( conn, return "" ); 429 return conn->cc_remid; 430 } 431 432 433 /* Receive next message. if timeout is not NULL, wait only until timeout */ 434 int fd_cnx_receive(struct cnxctx * conn, struct timespec * timeout, unsigned char **buf, size_t * len) 435 { 436 202 437 TODO("..."); 203 438 return ENOTSUP; 204 439 } 205 440 206 207 /* Get a string describing the remote peer address (ip address or fqdn) */ 208 char * fd_cnx_getremoteid(struct cnxctx * conn) 209 { 210 211 TODO("..."); 212 return NULL; 213 } 214 215 216 /* Receive next message. if timeout is not NULL, wait only until timeout */ 217 int fd_cnx_receive(struct cnxctx * conn, struct timespec * timeout, unsigned char **buf, size_t * len) 218 { 219 441 /* Set / reset alternate FIFO list to send FDEVP_CNX_MSG_RECV to when message is received */ 442 int fd_cnx_recv_setaltfifo(struct cnxctx * conn, struct fifo * alt_fifo) 443 { 444 TRACE_ENTRY( "%p %p", conn, alt_fifo ); 445 CHECK_PARAMS( conn ); 446 447 /* Let's cross fingers that there is no race condition here... */ 448 conn->cc_alt = alt_fifo; 449 450 return 0; 451 } 452 453 /* Send a message */ 454 int fd_cnx_send(struct cnxctx * conn, unsigned char * buf, size_t len) 455 { 456 220 457 TODO("..."); 221 458 return ENOTSUP; … … 223 460 224 461 225 /* Send a message */226 int fd_cnx_send(struct cnxctx * conn, unsigned char * buf, size_t len)227 {228 229 TODO("...");230 return ENOTSUP;231 }232 233 234 462 /* Destroy a conn structure, and shutdown the socket */ 235 463 void fd_cnx_destroy(struct cnxctx * conn) 236 464 { 237 238 TODO("..."); 465 TRACE_ENTRY("%p", conn); 466 467 CHECK_PARAMS_DO(conn, return); 468 469 TODO("End TLS session(s) if started"); 470 471 TODO("Stop manager thread if running"); 472 473 /* Shut the connection down */ 474 if (conn->cc_socket > 0) { 475 shutdown(conn->cc_socket, SHUT_RDWR); 476 } 477 478 TODO("Empty FIFO queues"); 479 480 /* Destroy FIFO lists */ 481 if (conn->cc_events) 482 CHECK_FCT_DO( fd_fifo_del ( &conn->cc_events ), /* continue */ ); 483 if (conn->cc_incoming) 484 CHECK_FCT_DO( fd_fifo_del ( &conn->cc_incoming ), /* continue */ ); 485 486 /* Free the object */ 487 free(conn); 488 489 /* Done! */ 239 490 return; 240 491 } -
freeDiameter/config.c
r20 r22 229 229 } 230 230 231 /* Validate local endpoints */ 232 if ((!FD_IS_LIST_EMPTY(&fd_g_config->cnf_endpoints)) && (fd_g_config->cnf_flags.no_ip4 || fd_g_config->cnf_flags.no_ip6)) { 233 struct fd_list * li; 234 for ( li = fd_g_config->cnf_endpoints.next; li != &fd_g_config->cnf_endpoints; li = li->next) { 235 struct fd_endpoint * ep = (struct fd_endpoint *)li; 236 if ( (fd_g_config->cnf_flags.no_ip4 && (ep->ss.ss_family == AF_INET)) 237 ||(fd_g_config->cnf_flags.no_ip6 && (ep->ss.ss_family == AF_INET6)) ) { 238 li = li->prev; 239 fd_list_unlink(&ep->chain); 240 if (TRACE_BOOL(INFO)) { 241 fd_log_debug("Info: Removing local address conflicting with the flags no_IP / no_IP6 : "); 242 sSA_DUMP_NODE( &ep->ss, AI_NUMERICHOST ); 243 fd_log_debug("\n"); 244 } 245 free(ep); 246 } 247 } 248 } 249 231 250 /* Configure TLS default parameters */ 232 251 if (! fd_g_config->cnf_sec_data.prio_string) { … … 239 258 } 240 259 if (! fd_g_config->cnf_sec_data.dh_bits) { 241 TRACE_DEBUG(FULL, "Generating DH parameters..."); 260 if (TRACE_BOOL(INFO)) { 261 fd_log_debug("Generating Diffie-Hellman parameters of size %d (this takes a few seconds)... ", GNUTLS_DEFAULT_DHBITS); 262 } 242 263 CHECK_GNUTLS_DO( gnutls_dh_params_generate2( 243 264 fd_g_config->cnf_sec_data.dh_cache, 244 265 GNUTLS_DEFAULT_DHBITS), 245 266 { TRACE_DEBUG(INFO, "Error in DH bits value : %d", GNUTLS_DEFAULT_DHBITS); return EINVAL; } ); 246 TRACE_DEBUG(FULL, "DH parameters generated."); 247 } 248 267 if (TRACE_BOOL(INFO)) { 268 fd_log_debug("Done!\n"); 269 } 270 } 249 271 250 272 return 0; -
freeDiameter/fD.h
r21 r22 157 157 ,FDEVP_TERMINATE 158 158 159 /* A connection object has received a message -- stored in event->data */ 160 ,FDEVP_CNX_MSG_RECV 161 159 162 /* A message was received in the peer */ 160 163 ,FDEVP_MSG_INCOMING … … 162 165 /* The PSM state is expired */ 163 166 ,FDEVP_PSM_TIMEOUT 167 164 168 }; 165 169 const char * fd_pev_str(int event); … … 196 200 void fd_servers_dump(); 197 201 int fd_servers_start(); 198 voidfd_servers_stop();202 int fd_servers_stop(); 199 203 200 204 /* Connection contexts */ 201 struct cnxctx * fd_cnx_init(int sock, int proto); 205 struct cnxctx * fd_cnx_serv_tcp(uint16_t port, int family, struct fd_endpoint * ep); 206 struct cnxctx * fd_cnx_serv_sctp(uint16_t port, struct fd_list * ep_list); 207 int fd_cnx_serv_listen(struct cnxctx * conn); 208 struct cnxctx * fd_cnx_serv_accept(struct cnxctx * serv); 209 struct cnxctx * fd_cnx_cli_connect(int proto, const sSA * sa, socklen_t addrlen); 210 char * fd_cnx_getid(struct cnxctx * conn); 202 211 int fd_cnx_start_clear(struct cnxctx * conn); 203 int fd_cnx_handshake(struct cnxctx * conn, int mode );212 int fd_cnx_handshake(struct cnxctx * conn, int mode, char * priority); 204 213 int fd_cnx_getcred(struct cnxctx * conn, const gnutls_datum_t **cert_list, unsigned int *cert_list_size); 205 int fd_cnx_getendpoints(struct cnxctx * conn, struct fd_list * senti);214 int fd_cnx_getendpoints(struct cnxctx * conn, struct fd_list * local, struct fd_list * remote); 206 215 char * fd_cnx_getremoteid(struct cnxctx * conn); 207 216 int fd_cnx_receive(struct cnxctx * conn, struct timespec * timeout, unsigned char **buf, size_t * len); 217 int fd_cnx_recv_setaltfifo(struct cnxctx * conn, struct fifo * alt_fifo); /* send FDEVP_CNX_MSG_RECV event to the fifo list */ 208 218 int fd_cnx_send(struct cnxctx * conn, unsigned char * buf, size_t len); 209 219 void fd_cnx_destroy(struct cnxctx * conn); 210 220 221 /* TCP */ 222 int fd_tcp_create_bind_server( int * sock, sSA * sa, socklen_t salen ); 223 int fd_tcp_listen( int sock ); 224 211 225 /* SCTP */ 212 226 #ifndef DISABLE_SCTP 213 int fd_sctp_create_bind_server( int * socket, uint16_t port ); 227 int fd_sctp_create_bind_server( int * sock, struct fd_list * list, uint16_t port ); 228 int fd_sctp_listen( int sock ); 229 214 230 int fd_sctp_get_str_info( int socket, int *in, int *out ); 215 231 -
freeDiameter/fdd.y
r20 r22 336 336 /* Now destroy any content in the structure */ 337 337 free(fddpi.pi_diamid); 338 free(fddpi.pi_sec_data.priority); 338 339 while (!FD_IS_LIST_EMPTY(&fddpi.pi_endpoints)) { 339 340 struct fd_list * li = fddpi.pi_endpoints.next; … … 415 416 fddpi.pi_port = (uint16_t)$4; 416 417 } 417 | peerparams SCTPSTREAMS '=' INTEGER ';'418 {419 CHECK_PARAMS_DO( ($4 > 0) && ($4 < 1<<16),420 { yyerror (&yylloc, conf, "Invalid value"); YYERROR; } );421 fddpi.pi_streams = (uint16_t)$4;422 }423 418 | peerparams TCTIMER '=' INTEGER ';' 424 419 { 425 420 fddpi.pi_tctimer = $4; 421 } 422 | peerparams TLS_PRIO '=' QSTRING ';' 423 { 424 fddpi.pi_sec_data.priority = $4; 426 425 } 427 426 | peerparams TWTIMER '=' INTEGER ';' -
freeDiameter/main.c
r20 r22 51 51 struct fd_config * fd_g_config = &conf; 52 52 53 /* gcrypt functions to support posix threads */ 53 54 GCRY_THREAD_OPTION_PTHREAD_IMPL; 54 55 … … 105 106 CHECK_FCT( fd_ext_load() ); 106 107 108 /* Start the servers */ 109 CHECK_FCT( fd_servers_start() ); 110 107 111 /* Start the peer state machines */ 108 112 CHECK_FCT( fd_psm_start() ); … … 154 158 155 159 /* cleanups */ 160 CHECK_FCT_DO( fd_servers_stop(), /* Stop accepting new connections */ ); 156 161 TODO("Stop dispatch thread(s) properly (no cancel yet)"); 157 162 CHECK_FCT_DO( fd_peer_fini(), /* Stop all connections */ ); -
freeDiameter/p_expiry.c
r16 r22 47 47 static void * gc_th_fct(void * arg) 48 48 { 49 fd_log_threadname ( "Peers/garb age" );50 TRACE_ENTRY( " ");49 fd_log_threadname ( "Peers/garb. col." ); 50 TRACE_ENTRY( "%p", arg ); 51 51 52 52 do { 53 53 struct fd_list * li, purge = FD_LIST_INITIALIZER(purge); 54 54 55 pthread_testcancel(); 56 sleep(GC_TIME); 55 sleep(GC_TIME); /* sleep is a cancellation point */ 57 56 58 57 /* Now check in the peers list if any peer can be deleted */ … … 96 95 { 97 96 fd_log_threadname ( "Peers/expire" ); 98 TRACE_ENTRY( " ");97 TRACE_ENTRY( "%p", arg ); 99 98 100 99 CHECK_POSIX_DO( pthread_mutex_lock(&exp_mtx), goto error ); … … 124 123 125 124 CHECK_POSIX_DO2( pthread_cond_timedwait( &exp_cnd, &exp_mtx, &first->p_exp_timer ), 126 ETIMEDOUT, /* ETIMEDOUT is a normal error, continue */,125 ETIMEDOUT, /* ETIMEDOUT is a normal return value, continue */, 127 126 /* on other error, */ goto error ); 128 127 -
freeDiameter/p_psm.c
r20 r22 55 55 #define case_str( _val )\ 56 56 case _val : return #_val 57 case_str(FDEVP_DUMP_ALL); 57 58 case_str(FDEVP_TERMINATE); 58 case_str(FDEVP_ DUMP_ALL);59 case_str(FDEVP_CNX_MSG_RECV); 59 60 case_str(FDEVP_MSG_INCOMING); 60 61 case_str(FDEVP_PSM_TIMEOUT); … … 241 242 psm_end: 242 243 pthread_cleanup_pop(1); /* set STATE_ZOMBIE */ 244 pthread_detach(peer->p_psm); 245 peer->p_psm = (pthread_t)NULL; 243 246 return NULL; 244 247 } … … 267 270 TRACE_ENTRY("%p", peer); 268 271 CHECK_PARAMS( CHECK_PEER(peer) ); 272 269 273 if (peer->p_hdr.info.pi_state != STATE_ZOMBIE) { 270 274 CHECK_FCT( fd_event_send(peer->p_events, FDEVP_TERMINATE, NULL) ); -
freeDiameter/peers.c
r20 r22 101 101 102 102 p->p_hdr.info.pi_lft = info->pi_lft; 103 p->p_hdr.info.pi_streams = info->pi_streams;104 103 p->p_hdr.info.pi_port = info->pi_port; 105 104 p->p_hdr.info.pi_tctimer = info->pi_tctimer; 106 105 p->p_hdr.info.pi_twtimer = info->pi_twtimer; 106 107 if (info->pi_sec_data.priority) { 108 CHECK_MALLOC( p->p_hdr.info.pi_sec_data.priority = strdup(info->pi_sec_data.priority) ); 109 } 107 110 108 111 /* Move the items from one list to the other */ … … 113 116 fd_list_insert_before(&p->p_hdr.info.pi_endpoints, li); 114 117 } 118 115 119 116 120 /* The internal data */ … … 229 233 230 234 if (p->p_cnxctx) { 231 TODO("destroy p->p_cnxctx");235 fd_cnx_destroy(p->p_cnxctx); 232 236 } 233 237 … … 293 297 list_empty = FD_IS_LIST_EMPTY(&fd_g_peers); 294 298 CHECK_FCT_DO( pthread_rwlock_unlock(&fd_g_peers_rw), /* continue */ ); 299 CHECK_SYS( clock_gettime(CLOCK_REALTIME, &now) ); 295 300 } 296 301 -
freeDiameter/sctp.c
r20 r22 36 36 #include "fD.h" 37 37 38 int fd_sctp_create_bind_server( int * socket, uint16_t port ) 38 /* Create a socket server and bind it according to daemon s configuration */ 39 int fd_sctp_create_bind_server( int * sock, struct fd_list * list, uint16_t port ) 39 40 { 40 41 TODO("Create sctp server, using fd_g_config: cnf_endpoints, no_ip4, no_ip6, cnf_sctp_str"); … … 43 44 } 44 45 46 /* Allow clients connections on server sockets */ 47 int fd_sctp_listen( int sock ) 48 { 49 TRACE_ENTRY("%d", sock); 50 CHECK_SYS( listen(sock, 5) ); 51 return 0; 52 } 53 54 /* Retrieve streams information from a connected association */ 45 55 int fd_sctp_get_str_info( int socket, int *in, int *out ) 46 56 { … … 49 59 return ENOTSUP; 50 60 } 61 -
freeDiameter/server.c
r21 r22 36 36 #include "fD.h" 37 37 38 /* This file contains the server (listening) part of the daemon */39 40 struct fd_list FD_SERVERS = FD_LIST_INITIALIZER(FD_SERVERS); /* The list of all server sockets */41 /* We don't need to protect this list, it is only accessed from the main thread. */42 43 /* Server (listening socket)information */38 /* Server (listening) part of the daemon */ 39 40 struct fd_list FD_SERVERS = FD_LIST_INITIALIZER(FD_SERVERS); /* The list of all server objects */ 41 /* We don't need to protect this list, it is only accessed from the main daemon thread. */ 42 43 /* Servers information */ 44 44 struct server { 45 45 struct fd_list chain; /* link in the FD_SERVERS list */ 46 46 47 int socket; /* server socket, or <= 0 */ 48 47 struct cnxctx * conn; /* server connection context (listening socket) */ 49 48 int proto; /* IPPROTO_TCP or IPPROTO_SCTP */ 50 49 int secur; /* TLS is started immediatly after connection ? */ 51 50 52 pthread_t serv_thr; /* The thread listening for new connections */ 53 int serv_status; /* 0 : not created; 1 : running; 2 : terminated */ 54 55 pthread_mutex_t clients_mtx; /* Mutex to protect the list of clients connected to the thread */ 56 struct fd_list clients; /* The list of clients connecting to this server, which information is not yet known */ 57 58 char * serv_name; /* A string to identify this server */ 51 pthread_t thr; /* The thread listening for new connections */ 52 int status; /* 0 : not created; 1 : running; 2 : terminated */ 53 54 struct fd_list clients; /* List of clients connected to this server, not yet identified */ 55 pthread_mutex_t clients_mtx; /* Mutex to protect the list of clients */ 59 56 }; 60 57 61 /* Client (connected remote endpoint, not received CER yet) information*/58 /* Client information (connecting peer for which we don't have the CER yet) */ 62 59 struct client { 63 60 struct fd_list chain; /* link in the server's list of clients */ 64 struct cnxctx *conn; /* Parameters of the connection ; sends its events to the ev fifo bellow*/65 struct timespec ts; /* De lay for receiving CER: INCNX_TIMEOUT*/66 pthread_t cli_thr; /* connection state machine (simplified PSM)*/61 struct cnxctx *conn; /* Parameters of the connection */ 62 struct timespec ts; /* Deadline for receiving CER (after INCNX_TIMEOUT) */ 63 pthread_t thr; /* connection state machine */ 67 64 }; 68 65 69 /* Parameter for the thread handling the new connected client, to avoid bloking the server thread */ 70 struct cli_fast { 71 struct server * serv; 72 int sock; 73 sSS ss; 74 socklen_t sslen; 75 }; 76 77 78 static void * client_simple_psm(void * arg) 66 67 /* Dump all servers information */ 68 void fd_servers_dump() 69 { 70 struct fd_list * li, *cli; 71 72 fd_log_debug("Dumping servers list :\n"); 73 for (li = FD_SERVERS.next; li != &FD_SERVERS; li = li->next) { 74 struct server * s = (struct server *)li; 75 fd_log_debug(" Serv %p '%s': %s, %s, %s\n", 76 s, fd_cnx_getid(s->conn), 77 IPPROTO_NAME( s->proto ), 78 s->secur ? "Secur" : "NotSecur", 79 (s->status == 0) ? "Thread not created" : 80 ((s->status == 1) ? "Thread running" : 81 ((s->status == 2) ? "Thread terminated" : 82 "Thread status unknown"))); 83 /* Dump the client list of this server */ 84 (void) pthread_mutex_lock(&s->clients_mtx); 85 for (cli = s->clients.next; cli != &s->clients; cli = cli->next) { 86 struct client * c = (struct client *)cli; 87 char bufts[128]; 88 fd_log_debug(" Connected: '%s' (timeout: %s)\n", 89 fd_cnx_getid(c->conn), 90 fd_log_time(&c->ts, bufts, sizeof(bufts))); 91 } 92 (void) pthread_mutex_unlock(&s->clients_mtx); 93 } 94 } 95 96 97 /* The state machine to handle incoming connection before the remote peer is identified */ 98 static void * client_sm(void * arg) 79 99 { 80 100 struct client * c = arg; … … 88 108 89 109 /* Name the current thread */ 90 { 91 char addr[128]; 92 snprintf(addr, sizeof(addr), "Srv %d/Cli %s", s->socket, fd_cnx_getremoteid(c->conn)); 93 fd_log_threadname ( addr ); 110 fd_log_threadname ( fd_cnx_getid(c->conn) ); 111 112 /* Handshake if we are a secure server port, or start clear otherwise */ 113 if (s->secur) { 114 int ret = fd_cnx_handshake(c->conn, GNUTLS_SERVER, NULL); 115 if (ret != 0) { 116 if (TRACE_BOOL(INFO)) { 117 fd_log_debug("TLS handshake failed for client '%s', connection aborted.\n", fd_cnx_getid(c->conn)); 118 } 119 goto cleanup; 120 } 121 } else { 122 CHECK_FCT_DO( fd_cnx_start_clear(c->conn), goto cleanup ); 94 123 } 95 124 … … 104 133 TODO("Message == CER : "); 105 134 TODO("Search matching peer"); 106 TODO("..."); 107 108 /* The end: we have freed the client structure already */ 109 TODO("Unlink the client structure"); 110 TODO(" pthread_detach(c->cli_thr); "); 111 TODO(" free(c); "); 135 TODO("Send event to the peer"); 136 137 /* The end */ 138 cleanup: 139 /* Unlink the client structure */ 140 CHECK_POSIX_DO( pthread_mutex_lock(&s->clients_mtx), goto fatal_error ); 141 fd_list_unlink( &c->chain ); 142 CHECK_POSIX_DO( pthread_mutex_unlock(&s->clients_mtx), goto fatal_error ); 143 144 /* Destroy the connection object if present */ 145 if (c->conn) 146 fd_cnx_destroy(c->conn); 147 148 /* Detach the thread, cleanup the client structure */ 149 pthread_detach(pthread_self()); 150 free(c); 112 151 return NULL; 113 152 … … 117 156 } 118 157 119 /* This thread is called when a new client had just connected */ 120 static void * handle_client_fast(void * arg) 121 { 122 struct cli_fast * cf = arg; 123 struct client * c = NULL; 124 125 /* Name the current thread */ 126 ASSERT(arg); 127 { 128 char addr[128]; 129 int offset = snprintf(addr, sizeof(addr), "Srv %d/CliFast %d : ", cf->serv->socket, cf->sock); 130 int rc = getnameinfo((sSA *)&cf->ss, sizeof(sSS), addr + offset, sizeof(addr) - offset, NULL, 0, 0); 131 if (rc) 132 memcpy(addr + offset, gai_strerror(rc), sizeof(addr) - offset); 133 134 fd_log_threadname ( addr ); 135 136 if (TRACE_BOOL(INFO)) { 137 fd_log_debug( "New connection %s, sock %d, from '%s'\n", cf->serv->serv_name, cf->sock, addr + offset); 138 } 139 } 140 141 /* Create a client structure */ 142 CHECK_MALLOC_DO( c = malloc(sizeof(struct client)), goto fatal_error ); 143 memset(c, 0, sizeof(struct client)); 144 fd_list_init(&c->chain, c); 145 146 /* Create the connection context */ 147 CHECK_MALLOC_DO( c->conn = fd_cnx_init(cf->sock, cf->serv->proto), goto fatal_error ); 148 149 /* In case we are a secure server, handshake now */ 150 if (cf->serv->secur) { 151 CHECK_FCT_DO( fd_cnx_handshake(c->conn, GNUTLS_CLIENT), goto cleanup ); 152 } 153 154 155 /* Save the client in the list */ 156 CHECK_POSIX_DO( pthread_mutex_lock( &cf->serv->clients_mtx ), goto fatal_error ); 157 fd_list_insert_before(&cf->serv->clients, &c->chain); 158 CHECK_POSIX_DO( pthread_mutex_unlock( &cf->serv->clients_mtx ), goto fatal_error ); 159 160 /* Start the client thread */ 161 CHECK_POSIX_DO( pthread_create( &c->cli_thr, NULL, client_simple_psm, c ), goto fatal_error ); 162 163 /* We're done here */ 164 free(cf); 165 return NULL; 166 167 cleanup: /* Clean all objects and return (minor error on the connection)*/ 168 if (c && c->conn) { 169 TODO( "Free the c->conn object & gnutls data" ); 170 } 171 172 return NULL; 173 174 fatal_error: /* This has effect to terminate the daemon */ 175 CHECK_FCT_DO(fd_event_send(fd_g_config->cnf_main_ev, FDEV_TERMINATE, NULL), ); 176 free(cf); 177 free(c); 178 return NULL; 179 } 180 181 /* The thread for the server */ 158 /* The thread managing a server */ 182 159 static void * serv_th(void * arg) 183 160 { 184 struct server *sv = (struct server *)arg; 185 struct cli_fast cf; 186 pthread_attr_t attr; 187 188 CHECK_PARAMS_DO(sv, goto error); 189 fd_log_threadname ( sv->serv_name ); 190 sv->serv_status = 1; 191 192 memset(&cf, 0, sizeof(struct cli_fast)); 193 cf.serv = sv; 194 195 CHECK_POSIX_DO( pthread_attr_init(&attr), goto error ); 196 CHECK_POSIX_DO( pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED), goto error ); 161 struct server *s = (struct server *)arg; 162 163 CHECK_PARAMS_DO(s, goto error); 164 fd_log_threadname ( fd_cnx_getid(s->conn) ); 165 s->status = 1; 197 166 198 167 /* Accept incoming connections */ 199 CHECK_ SYS_DO( listen(sv->socket, 5), goto error );168 CHECK_FCT_DO( fd_cnx_serv_listen(s->conn), goto error ); 200 169 201 170 do { 202 struct cli_fast * ncf; 203 pthread_t thr; 204 205 /* Re-init socket size */ 206 cf.sslen = sizeof(sSS); 171 struct client * c = NULL; 172 struct cnxctx * conn = NULL; 207 173 208 174 /* Wait for a new client */ 209 CHECK_ SYS_DO( cf.sock = accept(sv->socket, (sSA *)&cf.ss, &cf.sslen), goto error );175 CHECK_MALLOC_DO( conn = fd_cnx_serv_accept(s->conn), goto error ); 210 176 211 177 TRACE_DEBUG(FULL, "New connection accepted"); 212 178 213 /* Create the copy for the client thread */ 214 CHECK_MALLOC_DO( ncf = malloc(sizeof(struct cli_fast)), goto error ); 215 memcpy(ncf, &cf, sizeof(struct cli_fast)); 216 217 /* Create the thread to handle the new incoming connection */ 218 CHECK_POSIX_DO( pthread_create( &thr, &attr, handle_client_fast, ncf), goto error ); 179 /* Create a client structure */ 180 CHECK_MALLOC_DO( c = malloc(sizeof(struct client)), goto error ); 181 memset(c, 0, sizeof(struct client)); 182 fd_list_init(&c->chain, c); 183 c->conn = conn; 184 185 /* Save the client in the list */ 186 CHECK_POSIX_DO( pthread_mutex_lock( &s->clients_mtx ), goto error ); 187 fd_list_insert_before(&s->clients, &c->chain); 188 CHECK_POSIX_DO( pthread_mutex_unlock( &s->clients_mtx ), goto error ); 189 190 /* Start the client thread */ 191 CHECK_POSIX_DO( pthread_create( &c->thr, NULL, client_sm, c ), goto error ); 219 192 220 193 } while (1); 221 194 222 195 error: 223 if (s v)224 s v->serv_status = 2;196 if (s) 197 s->status = 2; 225 198 /* Send error signal to the daemon */ 226 199 TRACE_DEBUG(INFO, "An error occurred in server module! Thread is terminating..."); … … 232 205 233 206 /* Create a new server structure */ 234 static struct server * new_serv( int proto, int secur, int socket ) 235 { 236 char buf[32]; 237 char * sn = NULL; 207 static struct server * new_serv( int proto, int secur ) 208 { 238 209 struct server * new; 239 240 /* Create the server debug name */241 buf[sizeof(buf) - 1] = '\0';242 snprintf(buf, sizeof(buf) - 1, "Serv %d (%s%s)", socket, IPPROTO_NAME( proto ), secur ? "s" : "");243 CHECK_MALLOC_DO( sn = strdup(buf), return NULL );244 210 245 211 /* New server structure */ … … 248 214 memset(new, 0, sizeof(struct server)); 249 215 fd_list_init(&new->chain, new); 250 new->socket = socket;251 216 new->proto = proto; 252 217 new->secur = secur; … … 254 219 fd_list_init(&new->clients, new); 255 220 256 new->serv_name = sn;257 258 221 return new; 259 }260 261 /* Dump all servers information */262 void fd_servers_dump()263 {264 struct fd_list * li;265 266 fd_log_debug("Dumping servers list :\n");267 for (li = FD_SERVERS.next; li != &FD_SERVERS; li = li->next) {268 struct server * sv = (struct server *)li;269 fd_log_debug(" Serv '%s': %s(%d), %s, %s, %s\n",270 sv->serv_name,271 (sv->socket > 0) ? "Open" : "Closed", sv->socket,272 IPPROTO_NAME( sv->proto ),273 sv->secur ? "Secur" : "NotSecur",274 (sv->serv_status == 0) ? "Thread not created" :275 ((sv->serv_status == 1) ? "Thread running" :276 ((sv->serv_status == 2) ? "Thread terminated" :277 "Thread status unknown")));278 /* Dump the client list */279 TODO("Dump client list");280 }281 222 } 282 223 … … 284 225 int fd_servers_start() 285 226 { 286 int socket; 287 struct server * sv; 227 struct server * s; 228 229 int empty_conf_ep = FD_IS_LIST_EMPTY(&fd_g_config->cnf_endpoints); 288 230 289 231 /* SCTP */ … … 294 236 295 237 /* Create the server on default port */ 296 CHECK_FCT( fd_sctp_create_bind_server( &socket, fd_g_config->cnf_port ) ); 297 CHECK_MALLOC( sv = new_serv(IPPROTO_SCTP, 0, socket) ); 298 TODO("Link"); 299 TODO("Start thread"); 238 CHECK_MALLOC( s = new_serv(IPPROTO_SCTP, 0) ); 239 CHECK_MALLOC( s->conn = fd_cnx_serv_sctp(fd_g_config->cnf_port, FD_IS_LIST_EMPTY(&fd_g_config->cnf_endpoints) ? NULL : &fd_g_config->cnf_endpoints) ); 240 fd_list_insert_before( &FD_SERVERS, &s->chain ); 241 CHECK_POSIX( pthread_create( &s->thr, NULL, serv_th, s ) ); 242 243 /* Retrieve the list of endpoints if it was empty */ 244 if (empty_conf_ep) { 245 (void) fd_cnx_getendpoints(s->conn, &fd_g_config->cnf_endpoints, NULL); 246 } 300 247 301 248 /* Create the server on secure port */ 249 CHECK_MALLOC( s = new_serv(IPPROTO_SCTP, 1) ); 250 CHECK_MALLOC( s->conn = fd_cnx_serv_sctp(fd_g_config->cnf_port_tls, FD_IS_LIST_EMPTY(&fd_g_config->cnf_endpoints) ? NULL : &fd_g_config->cnf_endpoints) ); 251 fd_list_insert_before( &FD_SERVERS, &s->chain ); 252 CHECK_POSIX( pthread_create( &s->thr, NULL, serv_th, s ) ); 302 253 303 254 #endif /* DISABLE_SCTP */ … … 307 258 if (!fd_g_config->cnf_flags.no_tcp) { 308 259 309 if (FD_IS_LIST_EMPTY(&fd_g_config->cnf_endpoints)) { 310 /* if not no_IP : create server for 0.0.0.0 */ 311 /* if not no_IP6 : create server for :: */ 260 if (empty_conf_ep) { 261 /* Bind TCP servers on [0.0.0.0] */ 262 if (!fd_g_config->cnf_flags.no_ip4) { 263 264 CHECK_MALLOC( s = new_serv(IPPROTO_TCP, 0) ); 265 CHECK_MALLOC( s->conn = fd_cnx_serv_tcp(fd_g_config->cnf_port, AF_INET, NULL) ); 266 fd_list_insert_before( &FD_SERVERS, &s->chain ); 267 CHECK_POSIX( pthread_create( &s->thr, NULL, serv_th, s ) ); 268 269 CHECK_MALLOC( s = new_serv(IPPROTO_TCP, 1) ); 270 CHECK_MALLOC( s->conn = fd_cnx_serv_tcp(fd_g_config->cnf_port_tls, AF_INET, NULL) ); 271 fd_list_insert_before( &FD_SERVERS, &s->chain ); 272 CHECK_POSIX( pthread_create( &s->thr, NULL, serv_th, s ) ); 273 } 274 /* Bind TCP servers on [::] */ 275 if (!fd_g_config->cnf_flags.no_ip6) { 276 277 CHECK_MALLOC( s = new_serv(IPPROTO_TCP, 0) ); 278 CHECK_MALLOC( s->conn = fd_cnx_serv_tcp(fd_g_config->cnf_port, AF_INET6, NULL) ); 279 fd_list_insert_before( &FD_SERVERS, &s->chain ); 280 CHECK_POSIX( pthread_create( &s->thr, NULL, serv_th, s ) ); 281 282 CHECK_MALLOC( s = new_serv(IPPROTO_TCP, 1) ); 283 CHECK_MALLOC( s->conn = fd_cnx_serv_tcp(fd_g_config->cnf_port_tls, AF_INET6, NULL) ); 284 fd_list_insert_before( &FD_SERVERS, &s->chain ); 285 CHECK_POSIX( pthread_create( &s->thr, NULL, serv_th, s ) ); 286 } 312 287 } else { 313 288 /* Create all endpoints -- check flags */ 289 struct fd_list * li; 290 for (li = fd_g_config->cnf_endpoints.next; li != &fd_g_config->cnf_endpoints; li = li->next) { 291 struct fd_endpoint * ep = (struct fd_endpoint *)li; 292 sSA * sa = (sSA *) &ep->ss; 293 if (! ep->meta.conf) 294 continue; 295 if (fd_g_config->cnf_flags.no_ip4 && (sa->sa_family == AF_INET)) 296 continue; 297 if (fd_g_config->cnf_flags.no_ip6 && (sa->sa_family == AF_INET6)) 298 continue; 299 300 CHECK_MALLOC( s = new_serv(IPPROTO_TCP, 0) ); 301 CHECK_MALLOC( s->conn = fd_cnx_serv_tcp(fd_g_config->cnf_port, sa->sa_family, ep) ); 302 fd_list_insert_before( &FD_SERVERS, &s->chain ); 303 CHECK_POSIX( pthread_create( &s->thr, NULL, serv_th, s ) ); 304 305 CHECK_MALLOC( s = new_serv(IPPROTO_TCP, 1) ); 306 CHECK_MALLOC( s->conn = fd_cnx_serv_tcp(fd_g_config->cnf_port_tls, sa->sa_family, ep) ); 307 fd_list_insert_before( &FD_SERVERS, &s->chain ); 308 CHECK_POSIX( pthread_create( &s->thr, NULL, serv_th, s ) ); 309 } 314 310 } 315 311 } … … 319 315 320 316 /* Terminate all the servers */ 321 void fd_servers_stop() 322 { 317 int fd_servers_stop() 318 { 319 TODO("Not implemented"); 320 323 321 /* Loop on all servers */ 324 322 /* cancel thread */ 325 /* shutdown the socket */326 /* empty list of clients (stop them)*/327 } 323 /* destroy server connection context */ 324 /* cancel and destroy all clients */ 325 } -
include/freeDiameter/freeDiameter.h
r20 r22 256 256 /* Additional parameters */ 257 257 uint32_t pi_lft; /* lifetime of this peer when inactive (see pi_flags.exp definition) */ 258 uint16_t pi_streams; /* number of streams for SCTP. 0 = default */259 258 uint16_t pi_port; /* port to connect to. 0: default. */ 260 259 int pi_tctimer; /* use this value for TcTimer instead of global, if != 0 */ … … 271 270 struct fd_list pi_apps; /* applications advertised by the remote peer, except relay (pi_flags.relay) */ 272 271 struct { 272 char *priority; /* In case the default priority is not appropriate */ 273 273 /* This is inspired from http://www.gnu.org/software/gnutls/manual/gnutls.html#ex_003ax509_002dinfo */ 274 274 const gnutls_datum_t *cert_list; /* The (valid) credentials that the peer has presented */ -
include/freeDiameter/libfreeDiameter.h
r20 r22 120 120 * 121 121 * PARAMETERS: 122 * ts : The timestamp to log, or NULL for "now" 122 123 * buf : An array where the time must be stored 123 124 * len : size of the buffer 124 125 * 125 126 * DESCRIPTION: 126 * Writes the currenttimestamp (in human readable format) in a buffer.127 * Writes the timestamp (in human readable format) in a buffer. 127 128 * 128 129 * RETURN VALUE: 129 130 * pointer to buf. 130 131 */ 131 char * fd_log_time ( char * buf, size_t len );132 char * fd_log_time ( struct timespec * ts, char * buf, size_t len ); 132 133 133 134 … … 173 174 fd_log_debug("\t | tid:%-20s\t%s\tin %s@%s:%d\n" \ 174 175 "\t%s|%*s" format "\n", \ 175 __thn, fd_log_time( __buf, sizeof(__buf)), __PRETTY_FUNCTION__, __FILE__, __LINE__, \176 __thn, fd_log_time(NULL, __buf, sizeof(__buf)), __PRETTY_FUNCTION__, __FILE__, __LINE__, \ 176 177 (level < FULL)?"@":" ",level, "", ## args); \ 177 178 } \ -
libfreeDiameter/log.c
r2 r22 87 87 } 88 88 89 /* Write currenttime into a buffer */90 char * fd_log_time ( char * buf, size_t len )89 /* Write time into a buffer */ 90 char * fd_log_time ( struct timespec * ts, char * buf, size_t len ) 91 91 { 92 92 int ret; … … 96 96 97 97 /* Get current time */ 98 ret = clock_gettime(CLOCK_REALTIME, &tp); 99 if (ret != 0) { 100 snprintf(buf, len, "%s", strerror(ret)); 101 return buf; 98 if (!ts) { 99 ret = clock_gettime(CLOCK_REALTIME, &tp); 100 if (ret != 0) { 101 snprintf(buf, len, "%s", strerror(ret)); 102 return buf; 103 } 104 ts = &tp; 102 105 } 103 106 104 offset += strftime(buf + offset, len - offset, "%D,%T", localtime_r( &t p.tv_sec , &tm ));105 offset += snprintf(buf + offset, len - offset, ".%6.6ld", t p.tv_nsec / 1000);107 offset += strftime(buf + offset, len - offset, "%D,%T", localtime_r( &ts->tv_sec , &tm )); 108 offset += snprintf(buf + offset, len - offset, ".%6.6ld", ts->tv_nsec / 1000); 106 109 107 110 return buf;
Note: See TracChangeset
for help on using the changeset viewer.