Changeset 934:977a5375543c in freeDiameter for libfdcore
- Timestamp:
- Mar 8, 2013, 12:13:50 AM (12 years ago)
- Branch:
- default
- Phase:
- public
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
libfdcore/routing_dispatch.c
r754 r934 424 424 425 425 /* The DISPATCH message processing */ 426 static int msg_dispatch(struct msg * * pmsg)426 static int msg_dispatch(struct msg * msg) 427 427 { 428 428 struct msg_hdr * hdr; … … 432 432 char * ec = NULL; 433 433 char * em = NULL; 434 struct msg *msgptr = msg; 434 435 435 436 /* Read the message header */ 436 CHECK_FCT( fd_msg_hdr( *pmsg, &hdr) );437 CHECK_FCT( fd_msg_hdr(msg, &hdr) ); 437 438 is_req = hdr->msg_flags & CMD_FLAG_REQUEST; 438 439 … … 441 442 442 443 /* At this point, we need to understand the message content, so parse it */ 443 CHECK_FCT_DO( ret = fd_msg_parse_or_error( pmsg),444 CHECK_FCT_DO( ret = fd_msg_parse_or_error( &msgptr ), 444 445 { 445 446 /* in case of error */ 446 if ((ret == EBADMSG) && (*pmsg != NULL)) { 447 /* msg now contains the answer message to send back */ 448 CHECK_FCT( fd_fifo_post(fd_g_outgoing, pmsg) ); 449 } 450 if (*pmsg) { /* another error happen'd */ 451 fd_msg_log( FD_MSG_LOG_DROPPED, *pmsg, "An unexpected error occurred while parsing the message (%s)", strerror(ret)); 452 CHECK_FCT_DO( fd_msg_free(*pmsg), /* continue */); 453 *pmsg = NULL; 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 454 } 455 455 /* We're done with this one */ … … 464 464 465 465 /* Retrieve the corresponding query */ 466 CHECK_FCT( fd_msg_answ_getq( *pmsg, &qry ) );466 CHECK_FCT( fd_msg_answ_getq( msgptr, &qry ) ); 467 467 468 468 /* Retrieve any registered handler */ … … 473 473 474 474 TRACE_DEBUG(FULL, "Calling callback registered when query was sent (%p, %p)", anscb, data); 475 (*anscb)(data, pmsg);475 (*anscb)(data, &msgptr); 476 476 477 477 /* If the message is processed, we're done */ 478 if ( *pmsg== NULL) {478 if (msgptr == NULL) { 479 479 return 0; 480 480 } 481 482 /* otherwise continue the dispatching --hoping that the anscb callback did not mess with our message :) */ 481 483 } 482 484 } 483 485 484 486 /* Retrieve the session of the message */ 485 CHECK_FCT( fd_msg_sess_get(fd_g_config->cnf_dict, *pmsg, &sess, NULL) );487 CHECK_FCT( fd_msg_sess_get(fd_g_config->cnf_dict, msgptr, &sess, NULL) ); 486 488 487 489 /* Now, call any callback registered for the message */ 488 CHECK_FCT( fd_msg_dispatch ( pmsg, sess, &action, &ec) );490 CHECK_FCT( fd_msg_dispatch ( &msgptr, sess, &action, &ec) ); 489 491 490 492 /* Now, act depending on msg and action and ec */ 491 if ( *pmsg)493 if (msgptr) { 492 494 switch ( action ) { 493 495 case DISP_ACT_CONT: … … 495 497 if (!fd_g_config->cnf_flags.no_fwd) { 496 498 /* requeue to fd_g_outgoing */ 497 CHECK_FCT( fd_fifo_post(fd_g_outgoing, pmsg) );499 CHECK_FCT( fd_fifo_post(fd_g_outgoing, &msgptr) ); 498 500 break; 499 501 } … … 509 511 510 512 if (!is_req) { 511 fd_msg_log( FD_MSG_LOG_DROPPED, *pmsg, "Internal error: Answer received to locally issued request, but not handled by any handler."); 512 fd_msg_free(*pmsg); 513 *pmsg = NULL; 513 fd_msg_log( FD_MSG_LOG_DROPPED, msgptr, "Internal error: Answer received to locally issued request, but not handled by any handler."); 514 fd_msg_free(msgptr); 514 515 break; 515 516 } 516 517 517 518 /* Create an answer with the error code and message */ 518 CHECK_FCT( fd_msg_new_answer_from_req ( fd_g_config->cnf_dict, pmsg, 0 ) );519 CHECK_FCT( fd_msg_rescode_set( *pmsg, ec, em, NULL, 1 ) );519 CHECK_FCT( fd_msg_new_answer_from_req ( fd_g_config->cnf_dict, &msgptr, 0 ) ); 520 CHECK_FCT( fd_msg_rescode_set(msgptr, ec, em, NULL, 1 ) ); 520 521 521 522 case DISP_ACT_SEND: 522 523 /* Now, send the message */ 523 CHECK_FCT( fd_fifo_post(fd_g_outgoing, pmsg) ); 524 } 524 CHECK_FCT( fd_fifo_post(fd_g_outgoing, &msgptr) ); 525 } 526 } 525 527 526 528 /* We're done with dispatching this message */ … … 529 531 530 532 /* The ROUTING-IN message processing */ 531 static int msg_rt_in(struct msg * * pmsg)533 static int msg_rt_in(struct msg * msg) 532 534 { 533 535 struct msg_hdr * hdr; … … 536 538 DiamId_t qry_src = NULL; 537 539 size_t qry_src_len = 0; 540 struct msg *msgptr = msg; 538 541 539 542 /* Read the message header */ 540 CHECK_FCT( fd_msg_hdr( *pmsg, &hdr) );543 CHECK_FCT( fd_msg_hdr(msg, &hdr) ); 541 544 is_req = hdr->msg_flags & CMD_FLAG_REQUEST; 542 545 is_err = hdr->msg_flags & CMD_FLAG_ERROR; … … 544 547 /* Handle incorrect bits */ 545 548 if (is_req && is_err) { 546 CHECK_FCT( return_error( pmsg, "DIAMETER_INVALID_HDR_BITS", "R & E bits were set", NULL) );549 CHECK_FCT( return_error( &msgptr, "DIAMETER_INVALID_HDR_BITS", "R & E bits were set", NULL) ); 547 550 return 0; 548 551 } … … 564 567 TRACE_DEBUG(INFO, "Received a routable message with application id 0 or " _stringize(AI_RELAY) " (relay),\n" 565 568 " returning DIAMETER_APPLICATION_UNSUPPORTED"); 566 CHECK_FCT( return_error( pmsg, "DIAMETER_APPLICATION_UNSUPPORTED", "Routable message with application id 0 or relay", NULL) );569 CHECK_FCT( return_error( &msgptr, "DIAMETER_APPLICATION_UNSUPPORTED", "Routable message with application id 0 or relay", NULL) ); 567 570 return 0; 568 571 } else { … … 573 576 574 577 /* Parse the message for Dest-Host and Dest-Realm */ 575 CHECK_FCT( fd_msg_browse( *pmsg, MSG_BRW_FIRST_CHILD, &avp, NULL) );578 CHECK_FCT( fd_msg_browse(msgptr, MSG_BRW_FIRST_CHILD, &avp, NULL) ); 576 579 while (avp) { 577 580 struct avp_hdr * ahdr; … … 590 593 { 591 594 if (error_info.pei_errcode) { 592 CHECK_FCT( return_error( pmsg, error_info.pei_errcode, error_info.pei_message, error_info.pei_avp) );595 CHECK_FCT( return_error( &msgptr, error_info.pei_errcode, error_info.pei_message, error_info.pei_avp) ); 593 596 return 0; 594 597 } else { … … 610 613 { 611 614 if (error_info.pei_errcode) { 612 CHECK_FCT( return_error( pmsg, error_info.pei_errcode, error_info.pei_message, error_info.pei_avp) );615 CHECK_FCT( return_error( &msgptr, error_info.pei_errcode, error_info.pei_message, error_info.pei_avp) ); 613 616 return 0; 614 617 } else { … … 632 635 { 633 636 if (error_info.pei_errcode) { 634 CHECK_FCT( return_error( pmsg, error_info.pei_errcode, error_info.pei_message, error_info.pei_avp) );637 CHECK_FCT( return_error( &msgptr, error_info.pei_errcode, error_info.pei_message, error_info.pei_avp) ); 635 638 return 0; 636 639 } else { … … 657 660 /* Handle the missing routing AVPs first */ 658 661 if ( is_dest_realm == UNKNOWN ) { 659 CHECK_FCT( return_error( pmsg, "DIAMETER_COMMAND_UNSUPPORTED", "Non-routable message not supported (invalid bit ? missing Destination-Realm ?)", NULL) );662 CHECK_FCT( return_error( &msgptr, "DIAMETER_COMMAND_UNSUPPORTED", "Non-routable message not supported (invalid bit ? missing Destination-Realm ?)", NULL) ); 660 663 return 0; 661 664 } … … 665 668 if (is_local_app == YES) { 666 669 /* Ok, give the message to the dispatch thread */ 667 CHECK_FCT( fd_fifo_post(fd_g_local, pmsg) );670 CHECK_FCT( fd_fifo_post(fd_g_local, &msgptr) ); 668 671 } else { 669 672 /* We don't support the application, reply an error */ 670 CHECK_FCT( return_error( pmsg, "DIAMETER_APPLICATION_UNSUPPORTED", NULL, NULL) );673 CHECK_FCT( return_error( &msgptr, "DIAMETER_APPLICATION_UNSUPPORTED", NULL, NULL) ); 671 674 } 672 675 return 0; … … 676 679 if ((is_dest_host == NO) || (is_dest_realm == NO)) { 677 680 if (fd_g_config->cnf_flags.no_fwd) { 678 CHECK_FCT( return_error( pmsg, "DIAMETER_UNABLE_TO_DELIVER", "I am not a Diameter agent", NULL) );681 CHECK_FCT( return_error( &msgptr, "DIAMETER_UNABLE_TO_DELIVER", "I am not a Diameter agent", NULL) ); 679 682 return 0; 680 683 } … … 689 692 { 690 693 /* If the process failed, we assume it is because of the AVP format */ 691 CHECK_FCT( return_error( pmsg, "DIAMETER_INVALID_AVP_VALUE", "Failed to process decorated NAI", un) );694 CHECK_FCT( return_error( &msgptr, "DIAMETER_INVALID_AVP_VALUE", "Failed to process decorated NAI", un) ); 692 695 return 0; 693 696 } ); … … 696 699 if (is_nai) { 697 700 /* We have transformed the AVP, now submit it again in the queue */ 698 CHECK_FCT(fd_fifo_post(fd_g_incoming, pmsg) );701 CHECK_FCT(fd_fifo_post(fd_g_incoming, &msgptr) ); 699 702 return 0; 700 703 } … … 702 705 if (is_local_app == YES) { 703 706 /* Handle localy since we are able to */ 704 CHECK_FCT(fd_fifo_post(fd_g_local, pmsg) );707 CHECK_FCT(fd_fifo_post(fd_g_local, &msgptr) ); 705 708 return 0; 706 709 } … … 708 711 if (fd_g_config->cnf_flags.no_fwd) { 709 712 /* We return an error */ 710 CHECK_FCT( return_error( pmsg, "DIAMETER_APPLICATION_UNSUPPORTED", NULL, NULL) );713 CHECK_FCT( return_error( &msgptr, "DIAMETER_APPLICATION_UNSUPPORTED", NULL, NULL) ); 711 714 return 0; 712 715 } … … 720 723 721 724 /* Retrieve the corresponding query and its origin */ 722 CHECK_FCT( fd_msg_answ_getq( *pmsg, &qry ) );725 CHECK_FCT( fd_msg_answ_getq( msgptr, &qry ) ); 723 726 CHECK_FCT( fd_msg_source_get( qry, &qry_src, &qry_src_len ) ); 724 727 725 728 if ((!qry_src) && (!is_err)) { 726 729 /* The message is a normal answer to a request issued localy, we do not call the callbacks chain on it. */ 727 CHECK_FCT(fd_fifo_post(fd_g_local, pmsg) );730 CHECK_FCT(fd_fifo_post(fd_g_local, &msgptr) ); 728 731 return 0; 729 732 } … … 740 743 741 744 /* requests: dir = 1 & 2 => in order; answers = 3 & 2 => in reverse order */ 742 for ( li = (is_req ? rt_fwd_list.next : rt_fwd_list.prev) ; *pmsg&& (li != &rt_fwd_list) ; li = (is_req ? li->next : li->prev) ) {745 for ( li = (is_req ? rt_fwd_list.next : rt_fwd_list.prev) ; msgptr && (li != &rt_fwd_list) ; li = (is_req ? li->next : li->prev) ) { 743 746 struct rt_hdl * rh = (struct rt_hdl *)li; 744 747 int ret; … … 750 753 751 754 /* Ok, call this cb */ 752 TRACE_DEBUG(ANNOYING, "Calling next FWD callback on %p : %p", *pmsg, rh->rt_fwd_cb);753 CHECK_FCT_DO( ret = (*rh->rt_fwd_cb)(rh->cbdata, pmsg),755 TRACE_DEBUG(ANNOYING, "Calling next FWD callback on %p : %p", msgptr, rh->rt_fwd_cb); 756 CHECK_FCT_DO( ret = (*rh->rt_fwd_cb)(rh->cbdata, &msgptr), 754 757 { 755 fd_msg_log( FD_MSG_LOG_DROPPED, *pmsg, "Internal error: a FWD routing callback returned an error (%s)", strerror(ret));756 fd_msg_free( *pmsg);757 *pmsg= NULL;758 fd_msg_log( FD_MSG_LOG_DROPPED, msgptr, "Internal error: a FWD routing callback returned an error (%s)", strerror(ret)); 759 fd_msg_free(msgptr); 760 msgptr = NULL; 758 761 } ); 759 762 } … … 763 766 764 767 /* If a callback has handled the message, we stop now */ 765 if (! *pmsg)768 if (!msgptr) 766 769 return 0; 767 770 } … … 769 772 /* Now pass the message to the next step: either forward to another peer, or dispatch to local extensions */ 770 773 if (is_req || qry_src) { 771 CHECK_FCT(fd_fifo_post(fd_g_outgoing, pmsg) );774 CHECK_FCT(fd_fifo_post(fd_g_outgoing, &msgptr) ); 772 775 } else { 773 CHECK_FCT(fd_fifo_post(fd_g_local, pmsg) );776 CHECK_FCT(fd_fifo_post(fd_g_local, &msgptr) ); 774 777 } 775 778 … … 780 783 781 784 /* The ROUTING-OUT message processing */ 782 static int msg_rt_out(struct msg * * pmsg)785 static int msg_rt_out(struct msg * msg) 783 786 { 784 787 struct rt_data * rtd = NULL; … … 789 792 struct avp * avp; 790 793 struct rtd_candidate * c; 794 struct msg *msgptr = msg; 791 795 792 796 /* Read the message header */ 793 CHECK_FCT( fd_msg_hdr( *pmsg, &hdr) );797 CHECK_FCT( fd_msg_hdr(msgptr, &hdr) ); 794 798 is_req = hdr->msg_flags & CMD_FLAG_REQUEST; 795 799 … … 803 807 804 808 /* Retrieve the corresponding query and its origin */ 805 CHECK_FCT( fd_msg_answ_getq( *pmsg, &qry ) );809 CHECK_FCT( fd_msg_answ_getq( msgptr, &qry ) ); 806 810 CHECK_FCT( fd_msg_source_get( qry, &qry_src, &qry_src_len ) ); 807 811 … … 811 815 CHECK_FCT( fd_peer_getbyid( qry_src, qry_src_len, 0, (void *) &peer ) ); 812 816 if (fd_peer_getstate(peer) != STATE_OPEN) { 813 fd_msg_log( FD_MSG_LOG_DROPPED, *pmsg, "Unable to forward answer to deleted / closed peer '%s'.", qry_src); 814 fd_msg_free(*pmsg); 815 *pmsg = NULL; 817 fd_msg_log( FD_MSG_LOG_DROPPED, msgptr, "Unable to forward answer to deleted / closed peer '%s'.", qry_src); 818 fd_msg_free(msgptr); 816 819 return 0; 817 820 } … … 822 825 823 826 /* Push the message into this peer */ 824 CHECK_FCT( fd_out_send( pmsg, NULL, peer, 0) );827 CHECK_FCT( fd_out_send(&msgptr, NULL, peer, 0) ); 825 828 826 829 /* We're done with this answer */ … … 831 834 832 835 /* Get the routing data out of the message if any (in case of re-transmit) */ 833 CHECK_FCT( fd_msg_rt_get ( *pmsg, &rtd ) );836 CHECK_FCT( fd_msg_rt_get ( msgptr, &rtd ) ); 834 837 835 838 /* If there is no routing data already, let's create it */ … … 851 854 852 855 /* Now let's remove all peers from the Route-Records */ 853 CHECK_FCT( fd_msg_browse( *pmsg, MSG_BRW_FIRST_CHILD, &avp, NULL) );856 CHECK_FCT( fd_msg_browse(msgptr, MSG_BRW_FIRST_CHILD, &avp, NULL) ); 854 857 while (avp) { 855 858 struct avp_hdr * ahdr; … … 862 865 { 863 866 if (error_info.pei_errcode) { 864 CHECK_FCT( return_error( pmsg, error_info.pei_errcode, error_info.pei_message, error_info.pei_avp) );867 CHECK_FCT( return_error( &msgptr, error_info.pei_errcode, error_info.pei_message, error_info.pei_avp) ); 865 868 return 0; 866 869 } else { … … 883 886 fd_rtd_candidate_extract(rtd, &candidates, FD_SCORE_INI); 884 887 885 /* Pass the list to registered callbacks (even if it is empty ) */888 /* Pass the list to registered callbacks (even if it is empty list) */ 886 889 { 887 890 CHECK_FCT( pthread_rwlock_rdlock( &rt_out_lock ) ); … … 892 895 struct rt_hdl * rh = (struct rt_hdl *)li; 893 896 894 TRACE_DEBUG(ANNOYING, "Calling next OUT callback on %p : %p (prio %d)", *pmsg, rh->rt_out_cb, rh->prio);895 CHECK_FCT_DO( ret = (*rh->rt_out_cb)(rh->cbdata, *pmsg, candidates),897 TRACE_DEBUG(ANNOYING, "Calling next OUT callback on %p : %p (prio %d)", msgptr, rh->rt_out_cb, rh->prio); 898 CHECK_FCT_DO( ret = (*rh->rt_out_cb)(rh->cbdata, msgptr, candidates), 896 899 { 897 fd_msg_log( FD_MSG_LOG_DROPPED, *pmsg, "Internal error: an OUT routing callback returned an error (%s)", strerror(ret));898 fd_msg_free( *pmsg);899 *pmsg= NULL;900 fd_msg_log( FD_MSG_LOG_DROPPED, msgptr, "Internal error: an OUT routing callback returned an error (%s)", strerror(ret)); 901 fd_msg_free(msgptr); 902 msgptr = NULL; 900 903 break; 901 904 } ); … … 906 909 907 910 /* If an error occurred, skip to the next message */ 908 if (! *pmsg) {911 if (! msgptr) { 909 912 if (rtd) 910 913 fd_rtd_free(&rtd); … … 917 920 918 921 /* Save the routing information in the message */ 919 CHECK_FCT( fd_msg_rt_associate ( *pmsg, &rtd ) );922 CHECK_FCT( fd_msg_rt_associate ( msgptr, &rtd ) ); 920 923 921 924 /* Now try sending the message */ … … 934 937 if (fd_peer_getstate(peer) == STATE_OPEN) { 935 938 /* Send to this one */ 936 CHECK_FCT_DO( fd_out_send( pmsg, NULL, peer, 0), continue );939 CHECK_FCT_DO( fd_out_send(&msgptr, NULL, peer, 0), continue ); 937 940 938 941 /* If the sending was successful */ … … 942 945 943 946 /* If the message has not been sent, return an error */ 944 if ( *pmsg) {945 fd_msg_log( FD_MSG_LOG_NODELIVER, *pmsg, "No suitable candidate to route the message to." );946 return_error( pmsg, "DIAMETER_UNABLE_TO_DELIVER", "No suitable candidate to route the message to", NULL);947 if (msgptr) { 948 fd_msg_log( FD_MSG_LOG_NODELIVER, msgptr, "No suitable candidate to route the message to." ); 949 return_error( &msgptr, "DIAMETER_UNABLE_TO_DELIVER", "No suitable candidate to route the message to", NULL); 947 950 } 948 951 … … 977 980 978 981 /* This is the common thread code (same for routing and dispatching) */ 979 static void * process_thr(void * arg, int (*action_cb)(struct msg * * pmsg), struct fifo * queue, char * action_name)982 static void * process_thr(void * arg, int (*action_cb)(struct msg * msg), struct fifo * queue, char * action_name) 980 983 { 981 984 TRACE_ENTRY("%p %p %p %p", arg, action_cb, queue, action_name); … … 1040 1043 1041 1044 /* Now process the message */ 1042 CHECK_FCT_DO( (*action_cb)( &msg), goto fatal_error);1045 CHECK_FCT_DO( (*action_cb)(msg), goto fatal_error); 1043 1046 1044 1047 /* We're done with this message */
Note: See TracChangeset
for help on using the changeset viewer.