Changes in / [1106:8401adfb58f5:1105:6b4a417d2845] in freeDiameter
- Files:
-
- 2 deleted
- 18 edited
Legend:
- Unmodified
- Added
- Removed
-
extensions/CMakeLists.txt
r1103 r1040 86 86 87 87 FD_EXTENSION_SUBDIR(dbg_monitor "Outputs periodical status information" OFF) 88 FD_EXTENSION_SUBDIR(dbg_msg_timings "Show some timing information for messages" OFF)89 88 FD_EXTENSION_SUBDIR(dbg_rt "Routing extension for debugging the routing module" OFF) 90 89 FD_EXTENSION_SUBDIR(test_app "Testing application to send dummy message to another peer, like a Diameter 'ping'" OFF) -
include/freeDiameter/libfdcore.h
r1103 r1102 553 553 554 554 555 /* Parse a message against our dictionary, 556 return 0 in case of success. 557 log parsing error & return error code in case of failure in parsing. 558 In addition, if the error code is EBADMSG (the message does not follow our dictionary) 559 if *msg was a request, *msg is NULL and *error contains the error message ready to send back on return 560 if *msg was an answer, *msg is untouched and *error==*msg if *msg was an error message, *error is null otherwise */ 561 int fd_msg_parse_or_error( struct msg ** msg, struct msg **error ); 555 /* Parse a message against our dictionary, and in case of error log and eventually build the error reply (on return and EBADMSG, *msg == NULL or *msg is the error message ready to send) */ 556 int fd_msg_parse_or_error( struct msg ** msg ); 562 557 563 558 … … 931 926 - {peer} is set if the message is received from a peer's connection, and NULL if the message is from a new client 932 927 connected and not yet identified 933 - {other} is NULL , or a char * identifying the connection when {peer} is null.928 - {other} is NULL. 934 929 - {permsgdata} points to either a new empty structure allocated for this message or the one passed to HOOK_DATA_RECEIVED if used. 935 930 */ … … 964 959 */ 965 960 966 HOOK_MESSAGE_PARSING_ERROR,967 /* Hook called when a message being processed cannot be parsed successfully.968 - {msg} points to the message if buffer was parsed successfully, or NULL otherwise. You should not call fd_msg_parse_dict on this in any case.969 - {peer} is NULL or the peer that received the message. If NULL and the message is not NULL, you can still retrieve the source from the message itself.970 - {other} is a char * pointer to the error message (human-readable) if {msg} is not NULL, a pointer to struct fd_cnx_rcvdata containing the received buffer otherwise.971 - {permsgdata} points to existing structure associated with this message (or new structure if no previous hook was registered).972 */973 974 961 HOOK_MESSAGE_ROUTING_ERROR, 975 /* Hook called when a message being processed by the routing thread meets an error such as no remaining available peer for sending, based on routing callbacks decisions (maybe after retries). 962 /* Hook called when a message being processed by the routing thread meets an error such as: 963 -- parsing error 964 -- no remaining available peer for sending, based on routing callbacks decisions (maybe after retries). 976 965 - {msg} points to the message. Again, the objects may not have been dictionary resolved. If you 977 966 try to call fd_msg_parse_dict, it might slow down the operation of a relay agent, although this hook is not on the normal execution path. … … 1005 994 It is probably a good idea to log this for analysis / backup. 1006 995 - {msg} points to the message, which will be freed as soon as the hook returns. 1007 - {peer} may be NULL or a peer related to the event.996 - {peer} is NULL. 1008 997 - {other} is a char * pointer to the error message (human-readable). 1009 998 - {permsgdata} points to existing structure associated with this message (or new structure if no previous hook was registered). … … 1011 1000 1012 1001 HOOK_PEER_CONNECT_FAILED, 1013 /* Hook called when a connection attempt to /from a remote peer has failed. This hook is also called when the peer was in OPEN state and the connection is broken.1014 - {msg} may be NULL (lower layer error, e.g. connection timeout) or points to a message showing the error (either invalid incoming message, or the CEA message sent or receivedwith an error code).1002 /* Hook called when a connection attempt to a remote peer has failed. 1003 - {msg} may be NULL (lower layer error, e.g. connection timeout) or points to the CEA message sent or received (with an error code). 1015 1004 - {peer} may be NULL for incoming requests from unknown peers being rejected, otherwise it points to the peer structure associated with the attempt. 1016 1005 - {other} is a char * pointer to the error message (human-readable). … … 1019 1008 1020 1009 HOOK_PEER_CONNECT_SUCCESS, 1021 /* Hook called when a connection attempt to/from a remote peer has succeeded (the peer moves to OPEN_HANDSHAKE or OPEN state). 1022 In case of deprecated TLS handshake after the CER/CEA exchange, this hook can still be followed by HOOK_PEER_CONNECT_FAILED if TLS handshake fails. 1023 - {msg} points to the CEA message sent or received (with a success code) -- in case it is sent, you can always get access to the matching CER. 1010 /* Hook called when a connection attempt to a remote peer has succeeded (the peer moves to OPEN state). 1011 - {msg} points to the CEA message sent or received (with an success code) -- in case it is sent, you can always get access to the matching CER. 1024 1012 - {peer} points to the peer structure. 1025 1013 - {other} is NULL. … … 1081 1069 * 1082 1070 * PARAMETERS: 1083 * type_mask : A bitmask of fd_hook_type bits for which this cb is registered, e.g. ((1 << HOOK_MESSAGE_RECEIVED) | (1 << HOOK_MESSAGE_SENT))1071 * type_mask : A bitmask of fd_hook_type bits for which this cb is registered, e.g. ((1 << HOOK_MESSAGE_RECEIVED) || (1 << HOOK_MESSAGE_SENT)) 1084 1072 * fd_hook_cb : The callback function to register (see prototype above). 1085 1073 * regdata : Pointer to pass to the callback when it is called. The data is opaque to the daemon. … … 1105 1093 /* Remove a hook registration */ 1106 1094 int fd_hook_unregister( struct fd_hook_hdl * handler ); 1107 1108 1109 /* Use the following function to retrieve any pmd structure associated with a request matching the current answer. Returns NULL in case of error / no such structure */1110 struct fd_hook_permsgdata * fd_hook_get_request_pmd(struct fd_hook_data_hdl *data_hdl, struct msg * answer);1111 1095 1112 1096 -
include/freeDiameter/libfdproto.h
r1103 r1102 146 146 */ 147 147 void fd_log ( int, const char *, ... ) _ATTRIBUTE_PRINTFLIKE_(2,3); 148 #ifndef SWIG149 148 void fd_log_va( int, const char *, va_list args ); 150 #endif /* SWIG */151 149 152 150 /* these are internal objects of the debug facility, … … 611 609 DECLARE_FD_DUMP_PROTOTYPE(fd_sa_dump_node, sSA * sa, int flags); 612 610 DECLARE_FD_DUMP_PROTOTYPE(fd_sa_dump_node_serv, sSA * sa, int flags); 613 #define sSA_DUMP_STRLEN (INET6_ADDRSTRLEN + 1 + 32 + 2)614 void fd_sa_sdump_numeric(char * buf /* must be at least sSA_DUMP_STRLEN */, sSA * sa);615 611 616 612 -
libfdcore/cnxctx.c
r1103 r1102 228 228 CHECK_SYS_DO( cli_sock = accept(serv->cc_socket, (sSA *)&ss, &ss_len), return NULL ); 229 229 230 if (TRACE_BOOL(INFO)) { 231 char buf[1024]; 232 sSA_DUMP_NODE( buf, sizeof(buf), &ss, NI_NUMERICHOST ); 233 fd_log_debug("%s : accepted new client [%s].", fd_cnx_getid(serv), buf); 234 } 235 230 236 CHECK_MALLOC_DO( cli = fd_cnx_init(1), { shutdown(cli_sock, SHUT_RDWR); close(cli_sock); return NULL; } ); 231 237 cli->cc_socket = cli_sock; … … 258 264 snprintf(cli->cc_remid, sizeof(cli->cc_remid), "[err:%s]", gai_strerror(rc)); 259 265 } 260 261 LOG_D("Incoming connection: '%s' <- '%s' {%s}", fd_cnx_getid(serv), cli->cc_remid, cli->cc_id);262 266 263 267 #ifndef DISABLE_SCTP … … 271 275 cli->cc_sctp_para.pairs = cli->cc_sctp_para.str_in; 272 276 273 LOG_A("%s : client '%s' (SCTP:%d, %d/%d streams)", fd_cnx_getid(serv), fd_cnx_getid(cli), cli->cc_socket, cli->cc_sctp_para.str_in, cli->cc_sctp_para.str_out);277 TRACE_DEBUG(FULL,"%s : client '%s' (SCTP:%d, %d/%d streams)", fd_cnx_getid(serv), fd_cnx_getid(cli), cli->cc_socket, cli->cc_sctp_para.str_in, cli->cc_sctp_para.str_out); 274 278 } 275 279 #endif /* DISABLE_SCTP */ … … 283 287 int sock = 0; 284 288 struct cnxctx * cnx = NULL; 285 char sa_buf[sSA_DUMP_STRLEN];286 289 287 290 TRACE_ENTRY("%p %d", sa, addrlen); 288 291 CHECK_PARAMS_DO( sa && addrlen, return NULL ); 289 290 fd_sa_sdump_numeric(sa_buf, sa);291 292 292 293 /* Create the socket and connect, which can take some time and/or fail */ … … 294 295 int ret = fd_tcp_client( &sock, sa, addrlen ); 295 296 if (ret != 0) { 296 LOG_A("TCP connection to %s failed: %s", sa_buf, strerror(ret)); 297 int lvl; 298 switch (ret) { 299 case ECONNREFUSED: 300 301 /* "Normal" errors */ 302 lvl = FULL; 303 break; 304 default: 305 lvl = INFO; 306 } 307 /* Some errors are expected, we log at different level */ 308 TRACE_DEBUG( lvl, "fd_tcp_client returned an error: %s", strerror(ret)); 297 309 return NULL; 298 310 } 311 } 312 313 if (TRACE_BOOL(INFO)) { 314 char buf[1024]; 315 sSA_DUMP_NODE_SERV( buf, sizeof(buf), sa, NI_NUMERICSERV); 316 fd_log_debug("Connection established to server '%s' (TCP:%d).", buf, sock); 299 317 } 300 318 … … 311 329 /* Generate the names for the object */ 312 330 { 331 char addrbuf[INET6_ADDRSTRLEN]; 332 char portbuf[10]; 313 333 int rc; 314 334 315 snprintf(cnx->cc_id, sizeof(cnx->cc_id), "TCP,#%d->%s", cnx->cc_socket, sa_buf); 335 /* Numeric values for debug... */ 336 rc = getnameinfo(sa, addrlen, addrbuf, sizeof(addrbuf), portbuf, sizeof(portbuf), NI_NUMERICHOST | NI_NUMERICSERV); 337 if (rc) { 338 snprintf(addrbuf, sizeof(addrbuf), "[err:%s]", gai_strerror(rc)); 339 portbuf[0] = '\0'; 340 } 341 342 snprintf(cnx->cc_id, sizeof(cnx->cc_id), "TCP to [%s]:%s (%d)", addrbuf, portbuf, cnx->cc_socket); 316 343 317 344 /* ...Name for log messages */ … … 320 347 snprintf(cnx->cc_remid, sizeof(cnx->cc_remid), "[err:%s]", gai_strerror(rc)); 321 348 } 322 323 LOG_A("TCP connection to %s succeed (socket:%d).", sa_buf, sock);324 349 325 350 return cnx; … … 337 362 int sock = 0; 338 363 struct cnxctx * cnx = NULL; 339 char sa_buf[sSA_DUMP_STRLEN];340 364 sSS primary; 341 365 342 366 TRACE_ENTRY("%p", list); 343 367 CHECK_PARAMS_DO( list && !FD_IS_LIST_EMPTY(list), return NULL ); 344 345 fd_sa_sdump_numeric(sa_buf, &((struct fd_endpoint *)(list->next))->sa);346 368 347 369 { 348 370 int ret = fd_sctp_client( &sock, no_ip6, port, list ); 349 371 if (ret != 0) { 350 LOG_A("SCTP connection to [%s,...] failed: %s", sa_buf, strerror(ret)); 372 int lvl; 373 switch (ret) { 374 case ECONNREFUSED: 375 376 /* "Normal" errors */ 377 lvl = FULL; 378 break; 379 default: 380 lvl = INFO; 381 } 382 /* Some errors are expected, we log at different level */ 383 TRACE_DEBUG( lvl, "fd_sctp_client returned an error: %s", strerror(ret)); 351 384 return NULL; 352 385 } … … 370 403 cnx->cc_sctp_para.pairs = cnx->cc_sctp_para.str_in; 371 404 372 fd_sa_sdump_numeric(sa_buf, (sSA *)&primary); 405 if (TRACE_BOOL(INFO)) { 406 char buf[1024]; 407 sSA_DUMP_NODE_SERV( buf, sizeof(buf), &primary, NI_NUMERICSERV); 408 fd_log_debug("Connection established to server '%s' (SCTP:%d, %d/%d streams).", buf, sock, cnx->cc_sctp_para.str_in, cnx->cc_sctp_para.str_out); 409 } 373 410 374 411 /* Generate the names for the object */ 375 412 { 413 char addrbuf[INET6_ADDRSTRLEN]; 414 char portbuf[10]; 376 415 int rc; 377 416 378 snprintf(cnx->cc_id, sizeof(cnx->cc_id), "SCTP,#%d->%s", cnx->cc_socket, sa_buf); 417 /* Numeric values for debug... */ 418 rc = getnameinfo((sSA *)&primary, sSAlen(&primary), addrbuf, sizeof(addrbuf), portbuf, sizeof(portbuf), NI_NUMERICHOST | NI_NUMERICSERV); 419 if (rc) { 420 snprintf(addrbuf, sizeof(addrbuf), "[err:%s]", gai_strerror(rc)); 421 portbuf[0] = '\0'; 422 } 423 424 snprintf(cnx->cc_id, sizeof(cnx->cc_id), "SCTP to [%s]:%s (%d)", addrbuf, portbuf, cnx->cc_socket); 379 425 380 426 /* ...Name for log messages */ … … 383 429 snprintf(cnx->cc_remid, sizeof(cnx->cc_remid), "[err:%s]", gai_strerror(rc)); 384 430 } 385 386 LOG_A("SCTP connection to %s succeed (socket:%d, %d/%d streams).", sa_buf, sock, cnx->cc_sctp_para.str_in, cnx->cc_sctp_para.str_out);387 431 388 432 return cnx; … … 634 678 size_t fd_msg_pmdl_sizewithoverhead(size_t datalen) 635 679 { 636 return PMDL_PADDED(datalen) + sizeof(struct fd_msg_pmdl);680 return PMDL_PADDED(datalen); 637 681 } 638 682 … … 654 698 uint8_t * ret = NULL; 655 699 656 CHECK_MALLOC_DO( ret = malloc( fd_msg_pmdl_sizewithoverhead(expected_len) ), return NULL );700 CHECK_MALLOC_DO( ret = malloc( PMDL_PADDED(expected_len) ), return NULL ); 657 701 CHECK_FCT_DO( fd_cnx_init_msg_buffer(ret, expected_len, pmdl), {free(ret); return NULL;} ); 658 702 return ret; … … 663 707 uint8_t * ret = NULL; 664 708 665 CHECK_MALLOC_DO( ret = realloc( buffer, fd_msg_pmdl_sizewithoverhead(expected_len) ), return NULL );709 CHECK_MALLOC_DO( ret = realloc( buffer, PMDL_PADDED(expected_len) ), return NULL ); 666 710 CHECK_FCT_DO( fd_cnx_init_msg_buffer(ret, expected_len, pmdl), {free(ret); return NULL;} ); 667 711 return ret; … … 718 762 || (rcv_data.length > DIAMETER_MSG_SIZE_MAX)) { /* to avoid too big mallocs */ 719 763 /* The message is suspect */ 720 LOG_E( "Received suspect header [ver: %d, size: %zd] from '%s', assuming disconnection", (int)header[0], rcv_data.length, conn->cc_remid);764 LOG_E( "Received suspect header [ver: %d, size: %zd], assuming disconnection", (int)header[0], rcv_data.length); 721 765 fd_cnx_markerror(conn); 722 766 goto out; /* Stop the thread, the recipient of the event will cleanup */ … … 960 1004 || (rcv_data.length > DIAMETER_MSG_SIZE_MAX)) { /* to avoid too big mallocs */ 961 1005 /* The message is suspect */ 962 LOG_E( "Received suspect header [ver: %d, size: %zd] from '%s', assume disconnection", (int)header[0], rcv_data.length, conn->cc_remid);1006 LOG_E( "Received suspect header [ver: %d, size: %zd], assume disconnection", (int)header[0], rcv_data.length); 963 1007 fd_cnx_markerror(conn); 964 1008 goto out; -
libfdcore/hooks.c
r1103 r1098 186 186 in_msg = fd_msg_pmdl_get(msg); 187 187 ASSERT(in_msg && (in_msg->sentinel.o == NULL)); /* error / already initialized ??? */ 188 in_msg->sentinel.o = pmdl_free; 188 fd_list_init(&in_msg->sentinel, pmdl_free); 189 CHECK_POSIX_DO( pthread_mutex_init(&in_msg->lock, NULL), ); 189 190 /* Now move all items from the pmdl pointer into the initialized list */ 190 191 CHECK_POSIX_DO( pthread_mutex_lock(&pmdl->lock), ); … … 200 201 struct fd_hook_permsgdata * ret = NULL; 201 202 struct fd_list * li; 202 203 203 CHECK_POSIX_DO( pthread_mutex_lock(&pmdl->lock), ); 204 205 if (pmdl->sentinel.o == NULL) {206 pmdl->sentinel.o = pmdl_free;207 }208 204 209 205 /* Search in the list for an item with the same handle. The list is ordered by this handle */ … … 235 231 } 236 232 237 struct fd_hook_permsgdata * fd_hook_get_request_pmd(struct fd_hook_data_hdl *data_hdl, struct msg * answer)238 {239 struct msg * qry;240 struct fd_msg_pmdl *pmdl;241 struct fd_hook_permsgdata * ret = NULL;242 struct fd_list * li;243 244 CHECK_FCT_DO( fd_msg_answ_getq(answer, &qry), return NULL );245 if (!qry)246 return NULL;247 248 pmdl = fd_msg_pmdl_get(qry);249 if (!pmdl)250 return NULL;251 252 CHECK_POSIX_DO( pthread_mutex_lock(&pmdl->lock), );253 /* Search in the list for an item with the same handle. The list is ordered by this handle */254 for (li=pmdl->sentinel.next; li != &pmdl->sentinel; li = li->next) {255 struct pmd_list_item * pli = (struct pmd_list_item *) li;256 if (pli->hdl == data_hdl)257 ret = &pli->pmd;258 if (pli->hdl >= data_hdl)259 break;260 }261 CHECK_POSIX_DO( pthread_mutex_unlock(&pmdl->lock), );262 return ret;263 }264 233 265 234 /* The function that does the work of calling the extension's callbacks and also managing the permessagedata structures */ … … 268 237 struct fd_list * li; 269 238 ASSERT(type <= HOOK_PEER_LAST); 270 int call_default = 0;271 239 272 240 /* lock the list of hooks for this type */ 273 241 CHECK_POSIX_DO( pthread_rwlock_rdlock(&HS_array[type].rwlock), ); 274 242 275 if (FD_IS_LIST_EMPTY(&HS_array[type].sentinel)) { 276 call_default = 1; 277 } else { 278 /* for each registered hook */ 279 for (li = HS_array[type].sentinel.next; li != &HS_array[type].sentinel; li = li->next) { 280 struct fd_hook_hdl * h = (struct fd_hook_hdl *)li->o; 281 struct fd_hook_permsgdata * pmd = NULL; 282 283 /* do we need to handle pmd ? */ 284 if (h->data_hdl && pmdl) { 285 pmd = get_or_create_pmd(pmdl, h); 286 } 287 288 /* Now, call this callback */ 289 (*h->fd_hook_cb)(type, msg, &peer->p_hdr, other, pmd, h->regdata); 290 } 243 /* for each registered hook */ 244 for (li = HS_array[type].sentinel.next; li != &HS_array[type].sentinel; li = li->next) { 245 struct fd_hook_hdl * h = (struct fd_hook_hdl *)li->o; 246 struct fd_hook_permsgdata * pmd = NULL; 247 248 /* do we need to handle pmd ? */ 249 if (h->data_hdl && pmdl) { 250 pmd = get_or_create_pmd(pmdl, h); 251 } 252 253 /* Now, call this callback */ 254 (*h->fd_hook_cb)(type, msg, &peer->p_hdr, other, pmd, h->regdata); 291 255 } 292 256 293 257 /* done */ 294 258 CHECK_POSIX_DO( pthread_rwlock_unlock(&HS_array[type].rwlock), ); 295 296 if (call_default) { 297 char * buf = NULL; 298 size_t len = 0; 299 300 /* There was no registered handler, default behavior for this hook */ 301 switch (type) { 302 case HOOK_DATA_RECEIVED: { 303 struct fd_cnx_rcvdata *rcv_data = other; 304 LOG_A("RCV: %zd bytes", rcv_data->length); 305 break; 306 } 307 308 case HOOK_MESSAGE_RECEIVED: { 309 CHECK_MALLOC_DO(fd_msg_dump_summary(&buf, &len, NULL, msg, NULL, 0, 1), break); 310 LOG_D("RCV from '%s': %s", peer ? peer->p_hdr.info.pi_diamid : "<unknown>", buf); 311 break; 312 } 313 314 case HOOK_MESSAGE_LOCAL: { 315 CHECK_MALLOC_DO(fd_msg_dump_full(&buf, &len, NULL, msg, NULL, 0, 1), break); 316 LOG_A("Handled to framework for sending: %s", buf); 317 break; 318 } 319 320 case HOOK_MESSAGE_SENT: { 321 CHECK_MALLOC_DO(fd_msg_dump_summary(&buf, &len, NULL, msg, NULL, 0, 1), break); 322 LOG_D("SENT to '%s': %s", peer ? peer->p_hdr.info.pi_diamid : "<unknown>", buf); 323 break; 324 } 325 326 case HOOK_MESSAGE_FAILOVER: { 327 CHECK_MALLOC_DO(fd_msg_dump_summary(&buf, &len, NULL, msg, NULL, 0, 1), break); 328 LOG_D("Failing over message sent to '%s': %s", peer ? peer->p_hdr.info.pi_diamid : "<unknown>", buf); 329 break; 330 } 331 332 case HOOK_MESSAGE_PARSING_ERROR: { 333 if (msg) { 334 DiamId_t id = NULL; 335 size_t idlen; 336 if (!fd_msg_source_get( msg, &id, &idlen )) 337 id = (DiamId_t)"<error getting source>"; 338 339 if (!id) 340 id = (DiamId_t)"<local>"; 341 342 CHECK_MALLOC_DO(fd_msg_dump_treeview(&buf, &len, NULL, msg, NULL, 0, 1), break); 343 344 LOG_E("Parsing error: '%s' for the following message received from '%s':\n%s", (char *)other, (char *)id, buf); 345 } else { 346 struct fd_cnx_rcvdata *rcv_data = other; 347 CHECK_MALLOC_DO(fd_dump_extend_hexdump(&buf, &len, NULL, rcv_data->buffer, rcv_data->length, 0, 0), break); 348 LOG_E("Parsing error: cannot parse %zdB buffer from '%s': %s", rcv_data->length, peer ? peer->p_hdr.info.pi_diamid : "<unknown>", buf); 349 } 350 break; 351 } 352 353 case HOOK_MESSAGE_ROUTING_ERROR: { 354 DiamId_t id = NULL; 355 size_t idlen; 356 if (!fd_msg_source_get( msg, &id, &idlen )) 357 id = (DiamId_t)"<error getting source>"; 358 359 if (!id) 360 id = (DiamId_t)"<local>"; 361 362 CHECK_MALLOC_DO(fd_msg_dump_treeview(&buf, &len, NULL, msg, NULL, 0, 1), break); 363 364 LOG_E("Routing error: '%s' for the following message:\n%s", (char *)other, buf); 365 break; 366 } 367 368 case HOOK_MESSAGE_ROUTING_FORWARD: { 369 CHECK_MALLOC_DO(fd_msg_dump_summary(&buf, &len, NULL, msg, NULL, 0, 1), break); 370 LOG_D("FORWARDING: %s", buf); 371 break; 372 } 373 374 case HOOK_MESSAGE_ROUTING_LOCAL: { 375 CHECK_MALLOC_DO(fd_msg_dump_summary(&buf, &len, NULL, msg, NULL, 0, 1), break); 376 LOG_D("DISPATCHING: %s", buf); 377 break; 378 } 379 380 case HOOK_MESSAGE_DROPPED: { 381 CHECK_MALLOC_DO(fd_msg_dump_treeview(&buf, &len, NULL, msg, NULL, 0, 1), break); 382 LOG_E("Message discarded ('%s'):\n%s", (char *)other, buf); 383 break; 384 } 385 386 case HOOK_PEER_CONNECT_FAILED: { 387 if (msg) { 388 size_t offset = 0; 389 CHECK_MALLOC_DO(fd_dump_extend(&buf, &len, &offset, " CER/CEA dump:\n"), break); 390 CHECK_MALLOC_DO(fd_msg_dump_treeview(&buf, &len, &offset, msg, NULL, 0, 1), break); 391 LOG_N("Connection to '%s' failed: %s%s", peer ? peer->p_hdr.info.pi_diamid : "<unknown>", (char *)other, buf); 392 } else { 393 LOG_D("Connection to '%s' failed: %s", peer ? peer->p_hdr.info.pi_diamid : "<unknown>", (char *)other); 394 } 395 break; 396 } 397 398 case HOOK_PEER_CONNECT_SUCCESS: { 399 CHECK_MALLOC_DO(fd_msg_dump_treeview(&buf, &len, NULL, msg, NULL, 0, 1), break); 400 LOG_N("Connected to '%s', remote capabilities: %s", peer ? peer->p_hdr.info.pi_diamid : "<unknown>", buf); 401 break; 402 } 403 404 } 405 406 free(buf); 407 } 408 } 259 } -
libfdcore/messages.c
r1103 r1078 346 346 347 347 /* Parse a message against our dictionary, and in case of error log and eventually build the error reply -- returns the parsing status */ 348 int fd_msg_parse_or_error( struct msg ** msg , struct msg **error)348 int fd_msg_parse_or_error( struct msg ** msg ) 349 349 { 350 350 int ret = 0; … … 355 355 TRACE_ENTRY("%p", msg); 356 356 357 CHECK_PARAMS(msg && *msg && error);357 CHECK_PARAMS(msg && *msg); 358 358 m = *msg; 359 *error = NULL;360 359 361 360 /* Parse the message against our dictionary */ … … 365 364 return ret; /* 0 or another error */ 366 365 367 /* Log */368 fd_ hook_call(HOOK_MESSAGE_PARSING_ERROR, m, NULL, pei.pei_message ?: pei.pei_errcode, fd_msg_pmdl_get(m));366 TRACE_DEBUG(INFO, "A message does not comply to the dictionary and/or rules (%s)", pei.pei_errcode); 367 fd_msg_dump_walk(FULL, m); 369 368 370 369 CHECK_FCT( fd_msg_hdr(m, &hdr) ); … … 374 373 375 374 /* Create the error message */ 376 CHECK_FCT( fd_msg_new_answer_from_req ( fd_g_config->cnf_dict, &m, pei.pei_protoerr ? MSGFL_ANSW_ERROR : 0 ) );375 CHECK_FCT( fd_msg_new_answer_from_req ( fd_g_config->cnf_dict, msg, pei.pei_protoerr ? MSGFL_ANSW_ERROR : 0 ) ); 377 376 378 377 /* Set the error code */ 379 CHECK_FCT( fd_msg_rescode_set(m, pei.pei_errcode, pei.pei_message, pei.pei_avp, 1 ) ); 380 381 *msg = NULL; 382 *error = m; 378 CHECK_FCT( fd_msg_rescode_set(*msg, pei.pei_errcode, pei.pei_message, pei.pei_avp, 1 ) ); 383 379 384 380 } else { … … 413 409 default: /* Other errors */ 414 410 /* We let the application decide what to do with the message, we rescue it */ 415 *error = m;411 return 0; 416 412 } 417 413 } 418 414 } while (0); 415 416 /* Just discard */ 417 //fd_msg_log( FD_MSG_LOG_DROPPED, m, "Answer not compliant to dictionary's ABNF (%s)", pei.pei_errcode ); 418 CHECK_FCT( fd_msg_free( m ) ); 419 *msg = NULL; 419 420 } 420 421 -
libfdcore/p_ce.c
r1103 r1078 671 671 fd_cnx_destroy(initiator); 672 672 673 LOG_D("%s: Election lost on outgoing connection, closing and answering CEA on incoming connection.", peer->p_hdr.info.pi_diamid);674 675 673 /* Process with the receiver side */ 676 674 CHECK_FCT( fd_p_ce_process_receiver(peer) ); … … 680 678 memset(&pei, 0, sizeof(pei)); 681 679 pei.pei_errcode = "ELECTION_LOST"; 682 pei.pei_message = "Please answer my CER instead, you won the election.";683 LOG_D("%s: Election lost on incoming connection, closing and waiting for CEA on outgoing connection.", peer->p_hdr.info.pi_diamid);684 680 685 681 /* Answer an ELECTION LOST to the receiver side */ … … 724 720 if (req || ((st = fd_peer_getstate(peer)) != STATE_WAITCEA)) { 725 721 if (*msg) { 726 /* In such case, just discard the message */ 727 char buf[128]; 728 snprintf(buf, sizeof(buf), "Received while peer state machine was in state %s.", STATE_STR(st)); 729 fd_hook_call(HOOK_MESSAGE_DROPPED, *msg, peer, buf, fd_msg_pmdl_get(*msg)); 730 722 //fd_msg_log( FD_MSG_LOG_DROPPED, *msg, "Received CER/CEA while in '%s' state.", STATE_STR(st)); 731 723 CHECK_FCT_DO( fd_msg_free(*msg), /* continue */); 732 724 *msg = NULL; … … 739 731 740 732 /* Save info from the CEA into the peer */ 741 CHECK_FCT_DO( save_remote_CE_info(*msg, peer, &pei, &rc), 742 {743 fd_hook_call(HOOK_PEER_CONNECT_FAILED, *msg, peer, "An error occurred while processing incoming CEA.", NULL);744 goto cleanup;745 } );733 CHECK_FCT_DO( save_remote_CE_info(*msg, peer, &pei, &rc), goto cleanup ); 734 735 /* Dispose of the message, we don't need it anymore */ 736 CHECK_FCT_DO( fd_msg_free(*msg), /* continue */ ); 737 *msg = NULL; 746 738 747 739 /* Check the Result-Code */ 748 740 switch (rc) { 749 741 case ER_DIAMETER_SUCCESS: 750 /* Log success */751 fd_hook_call(HOOK_PEER_CONNECT_SUCCESS, *msg, peer, NULL, NULL);752 753 /* Dispose of the message, we don't need it anymore */754 CHECK_FCT_DO( fd_msg_free(*msg), /* continue */ );755 *msg = NULL;756 757 742 /* No problem, we can continue */ 758 743 break; … … 760 745 case ER_DIAMETER_TOO_BUSY: 761 746 /* Retry later */ 762 fd_hook_call(HOOK_PEER_CONNECT_FAILED, *msg, peer, "Remote peer is too busy", NULL);747 TRACE_DEBUG(INFO, "Peer %s replied a CEA with Result-Code AVP DIAMETER_TOO_BUSY, will retry later.", peer->p_hdr.info.pi_diamid); 763 748 fd_psm_cleanup(peer, 0); 764 749 fd_psm_next_timeout(peer, 0, 300); … … 772 757 default: 773 758 /* In any other case, we abort all attempts to connect to this peer */ 774 fd_hook_call(HOOK_PEER_CONNECT_FAILED, *msg, peer, "CEA with unexpected error code", NULL);759 TRACE_DEBUG(INFO, "Peer %s replied a CEA with Result-Code %d, aborting connection attempts.", peer->p_hdr.info.pi_diamid, rc); 775 760 return EINVAL; 776 761 } 777 778 762 779 763 /* Handshake if needed, start clear otherwise */ … … 794 778 { 795 779 /* Handshake failed ... */ 796 fd_ hook_call(HOOK_PEER_CONNECT_FAILED, NULL, peer, "TLS handshake failed after CER/CEA exchange", NULL);780 fd_log_debug("TLS Handshake failed with peer '%s', resetting the connection", peer->p_hdr.info.pi_diamid); 797 781 goto cleanup; 798 782 } ); … … 834 818 TRACE_ENTRY("%p", peer); 835 819 836 CHECK_FCT_DO( set_peer_cnx(peer, &peer->p_receiver), 837 { 838 fd_hook_call(HOOK_PEER_CONNECT_FAILED, NULL, peer, "Error saving the incoming connection in the peer structure", NULL); 839 return __ret__; 840 } ); 820 CHECK_FCT( set_peer_cnx(peer, &peer->p_receiver) ); 841 821 msg = peer->p_cer; 842 822 peer->p_cer = NULL; … … 948 928 CHECK_FCT( fd_msg_rescode_set(msg, "DIAMETER_SUCCESS", NULL, NULL, 0 ) ); 949 929 CHECK_FCT( add_CE_info(msg, peer->p_cnxctx, isi & PI_SEC_TLS_OLD, isi & PI_SEC_NONE) ); 950 951 /* The connection is complete, but we may still need TLS handshake */952 fd_hook_call(HOOK_PEER_CONNECT_SUCCESS, msg, peer, NULL, NULL);953 954 930 CHECK_FCT( fd_out_send(&msg, peer->p_cnxctx, peer, FD_CNX_ORDERED ) ); 955 931 … … 960 936 { 961 937 /* Handshake failed ... */ 962 fd_ hook_call(HOOK_PEER_CONNECT_FAILED, NULL, peer, "TLS handshake failed after CER/CEA exchange", NULL);938 fd_log_debug("TLS Handshake failed with peer '%s', resetting the connection", peer->p_hdr.info.pi_diamid); 963 939 goto cleanup; 964 940 } ); 965 941 966 942 /* Retrieve the credentials */ 967 CHECK_FCT_DO( fd_cnx_getcred(peer->p_cnxctx, &peer->p_hdr.info.runtime.pir_cert_list, &peer->p_hdr.info.runtime.pir_cert_list_size), 968 { 969 /* Error ... */ 970 fd_hook_call(HOOK_PEER_CONNECT_FAILED, NULL, peer, "Unable to retrieve remote credentials after TLS handshake", NULL); 971 goto cleanup; 972 } ); 973 943 CHECK_FCT( fd_cnx_getcred(peer->p_cnxctx, &peer->p_hdr.info.runtime.pir_cert_list, &peer->p_hdr.info.runtime.pir_cert_list_size) ); 974 944 975 945 /* Call second validation callback if needed */ … … 978 948 CHECK_FCT_DO( (*peer->p_cb2)( &peer->p_hdr.info ), 979 949 { 980 fd_hook_call(HOOK_PEER_CONNECT_FAILED, NULL, peer, "Validation callback rejected the peer after handshake", NULL);950 TRACE_DEBUG(INFO, "Validation callback rejected the peer %s after handshake", peer->p_hdr.info.pi_diamid); 981 951 CHECK_FCT( fd_psm_terminate( peer, "DO_NOT_WANT_TO_TALK_TO_YOU" ) ); 982 952 return 0; … … 1012 982 if (pei.pei_errcode) { 1013 983 /* Send the error */ 1014 fd_hook_call(HOOK_PEER_CONNECT_FAILED, msg, peer, pei.pei_message ?: pei.pei_errcode, NULL);1015 984 receiver_reject(&peer->p_cnxctx, &msg, &pei); 1016 } else {1017 char buf[1024];1018 snprintf(buf, sizeof(buf), "Unexpected error occurred while processing incoming connection from '%s'.", peer->p_hdr.info.pi_diamid);1019 fd_hook_call(HOOK_PEER_CONNECT_FAILED, msg, peer, buf, NULL);1020 985 } 1021 986 1022 987 cleanup: 1023 988 if (msg) { 989 //fd_msg_log(FD_MSG_LOG_DROPPED, msg, "An error occurred while processing a CER."); 1024 990 fd_msg_free(msg); 1025 991 } … … 1061 1027 1062 1028 /* Close initiator connection (was already set as principal) */ 1063 LOG_D("%s: Election lost on outgoing connection, closing and answering CEA on incoming connection.", peer->p_hdr.info.pi_diamid);1064 1029 fd_p_ce_clear_cnx(peer, NULL); 1065 1030 … … 1076 1041 pei.pei_errcode = "ELECTION_LOST"; 1077 1042 pei.pei_message = "Please answer my CER instead, you won the election."; 1078 LOG_D("%s: Election lost on incoming connection, closing and waiting for CEA on outgoing connection.", peer->p_hdr.info.pi_diamid);1079 1043 receiver_reject(cnx, msg, &pei); 1080 1044 } … … 1084 1048 pei.pei_errcode = "DIAMETER_UNABLE_TO_COMPLY"; /* INVALID COMMAND? in case of Capabilities-Updates? */ 1085 1049 pei.pei_message = "Invalid state to receive a new connection attempt."; 1086 LOG_E("%s: Rejecting new connection attempt while our state machine is in state '%s'", peer->p_hdr.info.pi_diamid, STATE_STR(cur_state));1087 1050 receiver_reject(cnx, msg, &pei); 1088 1051 } -
libfdcore/p_cnx.c
r1103 r974 236 236 if (FD_IS_LIST_EMPTY(&peer->p_connparams)) { 237 237 /* We encountered an error or we have looped over all the addresses of the peer. */ 238 fd_hook_call(HOOK_PEER_CONNECT_FAILED, NULL, peer, "All connection attempts failed, will retry later", NULL); 239 238 TRACE_DEBUG(INFO, "Unable to connect to the peer %s, aborting attempts for now.", peer->p_hdr.info.pi_diamid); 240 239 CHECK_FCT_DO( fatal_error = fd_event_send(peer->p_events, FDEVP_CNX_FAILED, 0, NULL), goto out ); 241 240 return NULL; … … 280 279 { 281 280 /* Handshake failed ... */ 282 fd_hook_call(HOOK_PEER_CONNECT_FAILED, NULL, peer, "TLS Handshake failed", NULL);281 TRACE_DEBUG(INFO, "TLS Handshake failed with peer '%s', resetting the connection", peer->p_hdr.info.pi_diamid); 283 282 fd_cnx_destroy(cnx); 284 283 empty_connection_list(peer); … … 286 285 goto out_pop; 287 286 } ); 288 LOG_A("%s: TLS handshake successful.", peer->p_hdr.info.pi_diamid);289 287 } else { 290 288 /* Prepare to receive the next message */ -
libfdcore/p_out.c
r1103 r1084 37 37 38 38 /* Alloc a new hbh for requests, bufferize the message and send on the connection, save in sentreq if provided */ 39 static int do_send(struct msg ** msg, uint32_t flags, struct cnxctx * cnx, uint32_t * hbh, struct fd_peer * peer)39 static int do_send(struct msg ** msg, uint32_t flags, struct cnxctx * cnx, uint32_t * hbh, struct sr_list * srl) 40 40 { 41 41 struct msg_hdr * hdr; … … 45 45 int ret; 46 46 uint32_t bkp_hbh = 0; 47 struct msg *cpy_for_logs_only; 48 49 TRACE_ENTRY("%p %x %p %p %p", msg, flags, cnx, hbh, peer); 47 48 TRACE_ENTRY("%p %x %p %p %p", msg, flags, cnx, hbh, srl); 50 49 51 50 /* Retrieve the message header */ … … 54 53 msg_is_a_req = (hdr->msg_flags & CMD_FLAG_REQUEST); 55 54 if (msg_is_a_req) { 56 CHECK_PARAMS(hbh && peer);55 CHECK_PARAMS(hbh && srl); 57 56 /* Alloc the hop-by-hop id and increment the value for next message */ 58 57 bkp_hbh = hdr->msg_hbhid; … … 65 64 pthread_cleanup_push( free, buf ); 66 65 67 cpy_for_logs_only = *msg;66 // cpy_for_logs_only = *msg; 68 67 69 68 /* Save a request before sending so that there is no race condition with the answer */ 70 69 if (msg_is_a_req) { 71 CHECK_FCT_DO( ret = fd_p_sr_store( &peer->p_sr, msg, &hdr->msg_hbhid, bkp_hbh), goto out );70 CHECK_FCT_DO( ret = fd_p_sr_store(srl, msg, &hdr->msg_hbhid, bkp_hbh), goto out ); 72 71 } 73 72 74 73 /* Log the message */ 75 fd_hook_call(HOOK_MESSAGE_SENT, cpy_for_logs_only, peer, NULL, fd_msg_pmdl_get(cpy_for_logs_only));74 // fd_msg_log( FD_MSG_LOG_SENT, cpy_for_logs_only, "Sent to '%s'", fd_cnx_getid(cnx)); 76 75 77 76 /* Send the message */ … … 128 127 129 128 /* Send the message, log any error */ 130 CHECK_FCT_DO( ret = do_send(&msg, 0, peer->p_cnxctx, &peer->p_hbh, peer),129 CHECK_FCT_DO( ret = do_send(&msg, 0, peer->p_cnxctx, &peer->p_hbh, &peer->p_sr), 131 130 { 132 131 if (msg) { … … 180 179 181 180 /* Do send the message */ 182 CHECK_FCT_DO( ret = do_send(msg, flags, cnx, hbh, peer ),181 CHECK_FCT_DO( ret = do_send(msg, flags, cnx, hbh, peer ? &peer->p_sr : NULL), 183 182 { 184 183 if (msg) { -
libfdcore/p_psm.c
r1104 r1085 336 336 peer->p_psm_timer.tv_sec += random() % 4; 337 337 peer->p_psm_timer.tv_nsec+= random() % 1000000000L; 338 if (peer->p_psm_timer.tv_nsec > =1000000000L) {338 if (peer->p_psm_timer.tv_nsec > 1000000000L) { 339 339 peer->p_psm_timer.tv_nsec -= 1000000000L; 340 340 peer->p_psm_timer.tv_sec ++; … … 483 483 struct msg * msg = NULL; 484 484 struct msg_hdr * hdr; 485 struct fd_cnx_rcvdata rcv_data;486 struct fd_msg_pmdl * pmdl = NULL;487 488 rcv_data.buffer = ev_data;489 rcv_data.length = ev_sz;490 pmdl = fd_msg_pmdl_get_inbuf(rcv_data.buffer, rcv_data.length);491 485 492 486 /* Parse the received buffer */ 493 487 CHECK_FCT_DO( fd_msg_parse_buffer( (void *)&ev_data, ev_sz, &msg), 494 488 { 495 fd_ hook_call(HOOK_MESSAGE_PARSING_ERROR, NULL, peer, &rcv_data, pmdl);489 fd_log_debug("Received invalid data from peer '%s', closing the connection", peer->p_hdr.info.pi_diamid); 496 490 free(ev_data); 497 491 CHECK_FCT_DO( fd_event_send(peer->p_events, FDEVP_CNX_ERROR, 0, NULL), goto psm_reset ); … … 499 493 } ); 500 494 501 fd_hook_associate(msg, pmdl);502 503 495 /* If the current state does not allow receiving messages, just drop it */ 504 496 if (cur_state == STATE_CLOSED) { 505 497 /* In such case, just discard the message */ 506 fd_hook_call(HOOK_MESSAGE_DROPPED, msg, peer, "Message purged from queue, peer in CLOSED state", fd_msg_pmdl_get(msg));498 //fd_msg_log( FD_MSG_LOG_DROPPED, msg, "Purged from peer '%s''s queue (CLOSED state).", peer->p_hdr.info.pi_diamid ); 507 499 fd_msg_free(msg); 508 500 goto psm_loop; 509 501 } 510 502 503 /* Log incoming message */ 504 //fd_msg_log( FD_MSG_LOG_RECEIVED, msg, "Received %zdb from '%s' (%s)", ev_sz, peer->p_hdr.info.pi_diamid, STATE_STR(cur_state) ); 505 511 506 /* Extract the header */ 512 507 CHECK_FCT_DO( fd_msg_hdr(msg, &hdr), goto psm_end ); … … 518 513 CHECK_FCT_DO( fd_p_sr_fetch(&peer->p_sr, hdr->msg_hbhid, &req), goto psm_end ); 519 514 if (req == NULL) { 520 fd_hook_call(HOOK_MESSAGE_DROPPED, msg, peer, "Answer received with no corresponding sent request.", fd_msg_pmdl_get(msg));515 //fd_msg_log( FD_MSG_LOG_DROPPED, msg, "Answer received with no corresponding sent request." ); 521 516 fd_msg_free(msg); 522 517 goto psm_loop; … … 526 521 CHECK_FCT_DO( fd_msg_answ_associate( msg, req ), goto psm_end ); 527 522 523 /* Display the delay to receive the answer */ 524 { 525 //fd_msg_log( FD_MSG_LOG_TIMING, msg, "Answer received in %ld.%6.6ld sec.", (long)delay.tv_sec, delay.tv_nsec / 1000 ); 526 } 528 527 } else { 529 528 /* Mark the incoming request so that we know we have pending answers for this peer */ … … 532 531 CHECK_POSIX_DO( pthread_mutex_unlock(&peer->p_state_mtx), goto psm_end ); 533 532 } 534 535 /* Log incoming message */536 fd_hook_call(HOOK_MESSAGE_RECEIVED, msg, peer, NULL, fd_msg_pmdl_get(msg));537 533 538 534 if (cur_state == STATE_OPEN_NEW) { … … 573 569 case STATE_WAITCEA: 574 570 case STATE_CLOSED: 575 default: {571 default: 576 572 /* In such case, just discard the message */ 577 char buf[128]; 578 snprintf(buf, sizeof(buf), "Received while peer state machine was in state %s.", STATE_STR(cur_state)); 579 fd_hook_call(HOOK_MESSAGE_DROPPED, msg, peer, buf, fd_msg_pmdl_get(msg)); 573 //fd_msg_log( FD_MSG_LOG_DROPPED, msg, "Received from peer '%s' while connection was not in state %s.", peer->p_hdr.info.pi_diamid, STATE_STR(cur_state) ); 580 574 fd_msg_free(msg); 581 }582 575 } 583 576 goto psm_loop; … … 586 579 /* Link-local message: They must be understood by our dictionary, otherwise we return an error */ 587 580 { 588 struct msg * error = NULL; 589 int ret = fd_msg_parse_or_error( &msg, &error ); 581 int ret = fd_msg_parse_or_error( &msg ); 590 582 if (ret != EBADMSG) { 591 CHECK_FCT_DO( ret, 592 { 593 LOG_E("%s: An unexpected error occurred while parsing a link-local message", peer->p_hdr.info.pi_diamid); 594 fd_msg_free(msg); 595 goto psm_end; 596 } ); 583 CHECK_FCT_DO( ret, goto psm_end ); 597 584 } else { 598 if (msg == NULL) {585 if (msg) { 599 586 /* Send the error back to the peer */ 600 CHECK_FCT_DO( ret = fd_out_send(& error, NULL, peer, FD_CNX_ORDERED), );601 if ( error) {587 CHECK_FCT_DO( ret = fd_out_send(&msg, NULL, peer, FD_CNX_ORDERED), ); 588 if (msg) { 602 589 /* Only if an error occurred & the message was not saved / dumped */ 603 LOG_E("%s: error sending a message", peer->p_hdr.info.pi_diamid);604 CHECK_FCT_DO( fd_msg_free( error), goto psm_end);590 //fd_msg_log( FD_MSG_LOG_DROPPED, msg, "Internal error: Problem while sending (%s)", strerror(ret) ); 591 CHECK_FCT_DO( fd_msg_free(msg), goto psm_end); 605 592 } 606 593 } else { 607 594 /* We received an invalid answer, let's disconnect */ 608 LOG_E("%s: Received invalid answer to Base protocol message, disconnecting...", peer->p_hdr.info.pi_diamid);609 CHECK_FCT_DO( fd_msg_free(msg), goto psm_end);610 595 CHECK_FCT_DO( fd_event_send(peer->p_events, FDEVP_CNX_ERROR, 0, NULL), goto psm_reset ); 611 596 } … … 617 602 switch (hdr->msg_code) { 618 603 case CC_CAPABILITIES_EXCHANGE: 619 CHECK_FCT_DO( fd_p_ce_msgrcv(&msg, (hdr->msg_flags & CMD_FLAG_REQUEST), peer), 620 { 621 if (msg) 622 CHECK_FCT_DO( fd_msg_free(msg), ); 623 goto psm_reset; 624 } ); 604 CHECK_FCT_DO( fd_p_ce_msgrcv(&msg, (hdr->msg_flags & CMD_FLAG_REQUEST), peer), goto psm_reset ); 625 605 break; 626 606 … … 691 671 /* Mark the connection problem */ 692 672 peer->p_flags.pf_cnx_pb = 1; 693 694 fd_hook_call(HOOK_PEER_CONNECT_FAILED, NULL, peer, "The connection was broken", NULL);695 673 696 674 /* Destroy the connection, restart the timer to a new connection attempt */ … … 754 732 } 755 733 if (params->cer) { 734 //fd_msg_log( FD_MSG_LOG_DROPPED, params->cer, "Internal error: this CER was not handled as expected." ); 756 735 CHECK_FCT_DO( fd_msg_free(params->cer), ); 757 736 params->cer = NULL; … … 774 753 case STATE_WAITCNXACK_ELEC: 775 754 case STATE_WAITCNXACK: 776 LOG_D("%s: Connection established", peer->p_hdr.info.pi_diamid);777 755 fd_p_ce_handle_newcnx(peer, cnx); 778 756 break; … … 803 781 804 782 case STATE_WAITCNXACK: 805 LOG_D("%s: Connection attempt failed", peer->p_hdr.info.pi_diamid);806 783 /* Go back to CLOSE */ 807 784 fd_psm_next_timeout(peer, 1, peer->p_hdr.info.config.pic_tctimer ?: fd_g_config->cnf_timer_tc); … … 826 803 827 804 case STATE_CLOSED: 828 LOG_D("%s: Connecting...", peer->p_hdr.info.pi_diamid);829 805 CHECK_FCT_DO( fd_psm_change_state(peer, STATE_WAITCNXACK), goto psm_end ); 830 806 fd_psm_next_timeout(peer, 0, CNX_TIMEOUT); … … 835 811 /* Mark the connection problem */ 836 812 peer->p_flags.pf_cnx_pb = 1; 813 case STATE_CLOSING: 837 814 case STATE_WAITCNXACK: 838 815 case STATE_WAITCEA: 839 fd_hook_call(HOOK_PEER_CONNECT_FAILED, NULL, peer, "Timeout while waiting for remote peer", NULL);840 case STATE_CLOSING:841 816 /* Destroy the connection, restart the timer to a new connection attempt */ 842 817 fd_psm_next_timeout(peer, 1, peer->p_hdr.info.config.pic_tctimer ?: fd_g_config->cnf_timer_tc); … … 874 849 875 850 psm_end: 876 LOG_N("%s: Going to ZOMBIE state (no more activity)", peer->p_hdr.info.pi_diamid);877 851 fd_psm_cleanup(peer, 1); 878 852 TRACE_DEBUG(INFO, "'%s'\t-> STATE_ZOMBIE (terminated)\t'%s'", -
libfdcore/peers.c
r1103 r1093 491 491 if (!avp_oh_model) { 492 492 avp_code_t code = AC_ORIGIN_HOST; 493 CHECK_FCT_DO( fd_dict_search ( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_CODE, &code, &avp_oh_model, ENOENT), 494 { LOG_E("Cannot find Origin-Host AVP definition in the dictionary!"); (void) pthread_mutex_unlock(&cache_avp_lock); return __ret__; } ); 493 int ret; 494 CHECK_FCT_DO( ret = fd_dict_search ( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_CODE, &code, &avp_oh_model, ENOENT), 495 { CHECK_POSIX( pthread_mutex_unlock(&cache_avp_lock) ); return ret; } ); 495 496 } 496 497 CHECK_POSIX( pthread_mutex_unlock(&cache_avp_lock) ); … … 503 504 /* First, check if the Origin-Host value is valid */ 504 505 if (!fd_os_is_valid_DiameterIdentity(avp_hdr->avp_value->os.data, avp_hdr->avp_value->os.len)) { 506 TRACE_DEBUG(INFO, "Received new CER with invalid Origin-Host"); 505 507 CHECK_FCT( fd_msg_new_answer_from_req ( fd_g_config->cnf_dict, cer, MSGFL_ANSW_ERROR ) ); 506 508 CHECK_FCT( fd_msg_rescode_set(*cer, "DIAMETER_INVALID_AVP_VALUE", 507 509 "Your Origin-Host contains invalid characters.", avp_oh, 1 ) ); 508 509 fd_hook_call(HOOK_PEER_CONNECT_FAILED, *cer, NULL, "Received CER with invalid Origin-Host AVP", NULL);510 511 510 CHECK_FCT( fd_out_send(cer, *cnx, NULL, FD_CNX_ORDERED) ); 512 511 return EINVAL; … … 546 545 peer->p_flags.pf_responder = 1; 547 546 peer->p_flags.pf_delete = 1; 548 549 LOG_D("Created new peer object for incoming CER: %s", peer->p_hdr.info.pi_diamid);550 547 551 548 #ifndef DISABLE_PEER_EXPIRY … … 594 591 *cer = NULL; 595 592 *cnx = NULL; 596 } else {597 char buf[1024];598 snprintf(buf, sizeof(buf), "An error occurred while processing new incoming CER: %s", strerror(ret));599 fd_hook_call(HOOK_PEER_CONNECT_FAILED, *cer, NULL, buf, NULL);600 593 } 601 594 -
libfdcore/routing_dispatch.c
r1103 r1078 432 432 char * ec = NULL; 433 433 char * em = NULL; 434 struct msg *msgptr = msg , *error = NULL;434 struct msg *msgptr = msg; 435 435 436 436 /* Read the message header */ … … 442 442 443 443 /* At this point, we need to understand the message content, so parse it */ 444 CHECK_FCT_DO( fd_msg_parse_or_error( &msgptr, &error ),444 CHECK_FCT_DO( ret = fd_msg_parse_or_error( &msgptr ), 445 445 { 446 int rescue = 0; 447 if (__ret__ != EBADMSG) { 448 fd_hook_call(HOOK_MESSAGE_DROPPED, msgptr, NULL, "Error while parsing received answer", fd_msg_pmdl_get(msgptr)); 449 fd_msg_free(msgptr); 450 } else { 451 if (!msgptr) { 452 /* error now contains the answer message to send back */ 453 CHECK_FCT( fd_fifo_post(fd_g_outgoing, &error) ); 454 } else if (!error) { 455 /* We have received an invalid answer to our query */ 456 fd_hook_call(HOOK_MESSAGE_DROPPED, msgptr, NULL, "Received answer failed the dictionary / rules parsing", fd_msg_pmdl_get(msgptr)); 457 fd_msg_free(msgptr); 458 } else { 459 /* We will pass the invalid received error to the application */ 460 rescue = 1; 461 } 462 } 463 if (!rescue) 464 return 0; /* We are done with this message, go to the next */ 446 /* in case of error */ 447 if ((ret == EBADMSG) && (msgptr != NULL)) { 448 /* msgptr now contains the answer message to send back */ 449 CHECK_FCT( fd_fifo_post(fd_g_outgoing, &msgptr) ); 450 } 451 if (msgptr) { /* another error happen'd */ 452 //fd_msg_log( FD_MSG_LOG_DROPPED, msgptr, "An unexpected error occurred while parsing the message (%s)", strerror(ret)); 453 CHECK_FCT_DO( fd_msg_free(msgptr), /* continue */); 454 } 455 /* We're done with this one */ 456 return 0; 465 457 } ); 466 458 -
libfdcore/server.c
r1103 r1093 134 134 struct client * c = arg; 135 135 struct server * s = NULL; 136 struct fd_cnx_rcvdata rcv_data;137 s truct fd_msg_pmdl * pmdl = NULL;136 uint8_t * buf = NULL; 137 size_t bufsz; 138 138 struct msg * msg = NULL; 139 139 struct msg_hdr *hdr = NULL; 140 struct fd_pei pei;141 140 142 141 TRACE_ENTRY("%p", c); … … 153 152 int ret = fd_cnx_handshake(c->conn, GNUTLS_SERVER, NULL, NULL); 154 153 if (ret != 0) { 155 char buf[1024]; 156 snprintf(buf, sizeof(buf), "TLS handshake failed for client '%s', connection aborted.", fd_cnx_getid(c->conn)); 157 158 fd_hook_call(HOOK_PEER_CONNECT_FAILED, NULL, NULL, buf, NULL); 159 154 if (TRACE_BOOL(INFO)) { 155 fd_log_debug("TLS handshake failed for client '%s', connection aborted.", fd_cnx_getid(c->conn)); 156 } 160 157 goto cleanup; 161 158 } … … 169 166 170 167 /* Receive the first Diameter message on the connection -- cleanup in case of timeout */ 171 CHECK_FCT_DO( fd_cnx_receive(c->conn, &c->ts, &rcv_data.buffer, &rcv_data.length), 172 { 173 char buf[1024]; 174 175 switch (__ret__) { 176 case ETIMEDOUT: 177 snprintf(buf, sizeof(buf), "Client '%s' did not send CER within %ds, connection aborted.", fd_cnx_getid(c->conn), INCNX_TIMEOUT); 178 fd_hook_call(HOOK_PEER_CONNECT_FAILED, NULL, NULL, buf, NULL); 179 break; 180 181 case ENOTCONN: 182 snprintf(buf, sizeof(buf), "Connection from '%s' in error before CER was received.", fd_cnx_getid(c->conn)); 183 fd_hook_call(HOOK_PEER_CONNECT_FAILED, NULL, NULL, buf, NULL); 184 break; 185 186 default: 187 snprintf(buf, sizeof(buf), "Connection from '%s': unspecified error, connection aborted.", fd_cnx_getid(c->conn)); 188 fd_hook_call(HOOK_PEER_CONNECT_FAILED, NULL, NULL, buf, NULL); 189 } 190 goto cleanup; 191 } ); 192 193 TRACE_DEBUG(FULL, "Received %zdb from new client '%s'", rcv_data.length, fd_cnx_getid(c->conn)); 194 195 pmdl = fd_msg_pmdl_get_inbuf(rcv_data.buffer, rcv_data.length); 168 CHECK_FCT_DO( fd_cnx_receive(c->conn, &c->ts, &buf, &bufsz), goto cleanup ); 169 170 TRACE_DEBUG(FULL, "Received %zdb from new client '%s'", bufsz, fd_cnx_getid(c->conn)); 196 171 197 172 /* Try parsing this message */ 198 CHECK_FCT_DO( fd_msg_parse_buffer( &rcv_data.buffer, rcv_data.length, &msg ), 199 { /* Parsing failed */ 200 fd_hook_call(HOOK_MESSAGE_PARSING_ERROR, NULL, NULL, &rcv_data, pmdl ); 201 goto cleanup; 202 } ); 173 CHECK_FCT_DO( fd_msg_parse_buffer( &buf, bufsz, &msg ), /* Parsing failed */ goto cleanup ); 203 174 204 175 /* Log incoming message */ 205 fd_hook_associate(msg, pmdl); 206 fd_hook_call(HOOK_MESSAGE_RECEIVED, msg, NULL, fd_cnx_getid(c->conn), fd_msg_pmdl_get(msg)); 176 //fd_msg_log( FD_MSG_LOG_RECEIVED, msg, "Received %zdb from new client '%s'", bufsz, fd_cnx_getid(c->conn) ); 207 177 208 178 /* We expect a CER, it must parse with our dictionary and rules */ 209 CHECK_FCT_DO( fd_msg_parse_rules( msg, fd_g_config->cnf_dict, &pei ), 210 { /* Parsing failed -- trace details */ 211 char buf[1024]; 212 213 fd_hook_call(HOOK_MESSAGE_PARSING_ERROR, msg, NULL, pei.pei_message ?: pei.pei_errcode, fd_msg_pmdl_get(msg)); 214 215 snprintf(buf, sizeof(buf), "Error parsing CER from '%s', connection aborted.", fd_cnx_getid(c->conn)); 216 fd_hook_call(HOOK_PEER_CONNECT_FAILED, NULL, NULL, buf, NULL); 217 218 goto cleanup; 219 } ); 179 CHECK_FCT_DO( fd_msg_parse_rules( msg, fd_g_config->cnf_dict, NULL ), /* Parsing failed -- trace details ? */ goto cleanup ); 220 180 221 181 /* Now check we received a CER */ 222 182 CHECK_FCT_DO( fd_msg_hdr ( msg, &hdr ), goto fatal_error ); 223 183 CHECK_PARAMS_DO( (hdr->msg_appl == 0) && (hdr->msg_flags & CMD_FLAG_REQUEST) && (hdr->msg_code == CC_CAPABILITIES_EXCHANGE), 224 { /* Parsing failed -- trace details */ 225 char buf[1024]; 226 snprintf(buf, sizeof(buf), "Expected CER from '%s', received a different message, connection aborted.", fd_cnx_getid(c->conn)); 227 fd_hook_call(HOOK_PEER_CONNECT_FAILED, msg, NULL, buf, NULL); 228 goto cleanup; 229 } ); 184 { fd_log_debug("Connection '%s', expecting CER, received something else, closing...", fd_cnx_getid(c->conn)); goto cleanup; } ); 230 185 231 186 /* Finally, pass the information to the peers module which will handle it next */ … … 245 200 /* Cleanup the parsed message if any */ 246 201 if (msg) { 202 //fd_msg_log( FD_MSG_LOG_DROPPED, msg, "Received invalid/unexpected message from connecting client '%s'", fd_cnx_getid(c->conn) ); 247 203 CHECK_FCT_DO( fd_msg_free(msg), /* continue */); 248 204 } … … 253 209 254 210 /* Cleanup the received buffer if any */ 255 free( rcv_data.buffer);211 free(buf); 256 212 257 213 /* Detach the thread, cleanup the client structure */ … … 283 239 /* Wait for a new client or cancel */ 284 240 CHECK_MALLOC_DO( conn = fd_cnx_serv_accept(s->conn), goto error ); 241 242 TRACE_DEBUG(FULL, "New connection accepted"); 285 243 286 244 /* Create a client structure */ … … 303 261 if (s) 304 262 set_status(s, TERMINATED); 305 306 /* Send error signal to the core */ 307 LOG_F( "An error occurred in server module! Thread is terminating..."); 263 /* Send error signal to the daemon */ 264 TRACE_DEBUG(INFO, "An error occurred in server module! Thread is terminating..."); 308 265 CHECK_FCT_DO(fd_event_send(fd_g_config->cnf_main_ev, FDEV_TERMINATE, 0, NULL), ); 309 266 -
libfdproto/fifo.c
r1104 r1093 412 412 CHECK_MALLOC_DO( new = malloc (sizeof (struct fifo_item)) , { 413 413 pthread_mutex_unlock( &queue->mtx ); 414 return ENOMEM;415 414 } ); 416 415 … … 471 470 ASSERT( ! FD_IS_LIST_EMPTY(&queue->list) ); 472 471 473 fi = (struct fifo_item *)(queue->list.next); 474 ret = fi->item.o; 472 fi = (struct fifo_item *)queue->list.next; 475 473 fd_list_unlink(&fi->item); 476 474 queue->count--; 477 475 queue->total_items++; 476 ret = fi->item.o; 478 477 479 478 /* Update the timings */ … … 579 578 static int fifo_tget ( struct fifo * queue, void ** item, int istimed, const struct timespec *abstime) 580 579 { 580 int timedout = 0; 581 581 int call_cb = 0; 582 int ret = 0;583 582 584 583 /* Check the parameters */ … … 599 598 return EPIPE; 600 599 } 601 600 602 601 if (queue->count > 0) { 603 602 /* There are items in the queue, so pick the first one */ … … 605 604 call_cb = test_l_cb(queue); 606 605 } else { 606 int ret = 0; 607 607 /* We have to wait for a new item */ 608 608 queue->thrs++ ; … … 618 618 goto awaken; /* test for spurious wake-ups */ 619 619 620 /* otherwise (ETIMEDOUT / other error) just continue */ 620 if (istimed && (ret == ETIMEDOUT)) { 621 timedout = 1; 622 } else { 623 /* Unexpected error condition (means we need to debug) */ 624 ASSERT( ret == 0 /* never true */ ); 625 } 621 626 } 622 627 … … 629 634 630 635 /* Done */ 631 return ret;636 return timedout ? ETIMEDOUT : 0; 632 637 } 633 638 -
libfdproto/messages.c
r1103 r1101 202 202 init_chain( &msg->msg_chain, MSG_MSG); 203 203 msg->msg_eyec = MSG_MSG_EYEC; 204 205 fd_list_init(&msg->msg_pmdl.sentinel, NULL);206 CHECK_POSIX_DO( pthread_mutex_init(&msg->msg_pmdl.lock, NULL), );207 204 } 208 205 … … 1955 1952 CHECK_PARAMS( buffer && *buffer && msg && (buflen >= GETMSGHDRSZ()) ); 1956 1953 buf = *buffer; 1954 *buffer = NULL; 1957 1955 1958 1956 if ( buf[0] != DIAMETER_VERSION) { 1959 1957 TRACE_DEBUG(INFO, "Invalid version in message: %d (supported: %d)", buf[0], DIAMETER_VERSION); 1958 free(buf); 1960 1959 return EBADMSG; 1961 1960 } … … 1964 1963 if ( buflen < msglen ) { 1965 1964 TRACE_DEBUG(INFO, "Truncated message (%zd / %d)", buflen, msglen ); 1965 free(buf); 1966 1966 return EBADMSG; 1967 1967 } 1968 1968 1969 1969 /* Create a new object */ 1970 CHECK_MALLOC ( new = malloc (sizeof(struct msg)));1970 CHECK_MALLOC_DO( new = malloc (sizeof(struct msg)), { free(buf); return ENOMEM; } ); 1971 1971 1972 1972 /* Initialize the fields */ … … 1984 1984 new->msg_public.msg_eteid = ntohl(*(uint32_t *)(buf+16)); 1985 1985 1986 new->msg_rawbuffer = buf; 1987 1986 1988 /* Parse the AVP list */ 1987 1989 CHECK_FCT_DO( ret = parsebuf_list(buf + GETMSGHDRSZ(), buflen - GETMSGHDRSZ(), &new->msg_chain.children), { destroy_tree(_C(new)); return ret; } ); 1988 1990 1989 /* Parsing successful */1990 new->msg_rawbuffer = buf;1991 *buffer = NULL;1992 1991 *msg = new; 1993 1992 return 0; -
libfdproto/utils.c
r1103 r1093 66 66 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "%s", gai_strerror(rc)), return NULL); 67 67 } else { 68 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "%s (s)", &addrbuf[0], &servbuf[0]), return NULL);68 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "%s", &addrbuf[0]), return NULL); 69 69 } 70 70 } else { … … 73 73 return *buf; 74 74 } 75 76 void fd_sa_sdump_numeric(char * buf /* must be at least sSA_DUMP_STRLEN */, sSA * sa)77 {78 char addrbuf[INET6_ADDRSTRLEN];79 char servbuf[32];80 81 if (sa) {82 int rc = getnameinfo(sa, sSAlen( sa ), addrbuf, sizeof(addrbuf), servbuf, sizeof(servbuf), NI_NUMERICHOST | NI_NUMERICSERV);83 if (rc) {84 snprintf(buf, sSA_DUMP_STRLEN, "%s", gai_strerror(rc));85 } else {86 snprintf(buf, sSA_DUMP_STRLEN, "%s(%s)", addrbuf, servbuf);87 }88 } else {89 snprintf(buf, sSA_DUMP_STRLEN, "(NULL / ANY)");90 }91 92 } -
tests/testmesg.c
r1103 r1088 757 757 { 758 758 unsigned char * buftmp = NULL; 759 struct msg * error;760 759 /* Check the parse or error works as expected */ 761 760 CPYBUF(); … … 766 765 CHECK( 0, fd_msg_init() ); 767 766 CHECK( 0, fd_msg_parse_buffer( &buf_cpy, 344, &msg) ); 768 CHECK( EBADMSG, fd_msg_parse_or_error( &msg, &error ) ); 769 CHECK( NULL, msg ); 770 msg = error; 767 CHECK( EBADMSG, fd_msg_parse_or_error( &msg ) ); 771 768 772 769 CHECK( 0, fd_msg_bufferize( msg, &buftmp, NULL ) ); -
tests/tests.h
r1103 r1090 206 206 CHECK( 0, fd_libproto_init() ); 207 207 208 CHECK( 0, fd_hooks_init() );209 210 208 fd_log_threadname(fname); 211 209
Note: See TracChangeset
for help on using the changeset viewer.