Changeset 88:9e2db1647d6f in freeDiameter
- Timestamp:
- Dec 7, 2009, 3:51:09 PM (14 years ago)
- Branch:
- default
- Phase:
- public
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
freeDiameter/routing.c
r87 r88 266 266 { 267 267 struct fd_peer * peer; 268 int is_loc = 0; 268 269 269 270 /* Get the source of the message */ … … 272 273 CHECK_FCT( fd_msg_source_get( msg, &id ) ); 273 274 274 /* Search the peer with this id */ 275 CHECK_FCT( fd_peer_getbyid( id, (void *)&peer ) ); 276 277 if (!peer) { 278 TRACE_DEBUG(INFO, "Unable to send error '%s' to deleted peer '%s' in reply to:", error_code, id); 279 fd_msg_dump_walk(INFO, msg); 280 fd_msg_free(msg); 281 return 0; 275 if (id == NULL) { 276 is_loc = 1; /* The message was issued locally */ 277 } else { 278 279 /* Search the peer with this id */ 280 CHECK_FCT( fd_peer_getbyid( id, (void *)&peer ) ); 281 282 if (!peer) { 283 TRACE_DEBUG(INFO, "Unable to send error '%s' to deleted peer '%s' in reply to:", error_code, id); 284 fd_msg_dump_walk(INFO, msg); 285 fd_msg_free(msg); 286 return 0; 287 } 282 288 } 283 289 } … … 290 296 291 297 /* Send the answer */ 292 CHECK_FCT( fd_out_send(&msg, NULL, peer) ); 298 if (is_loc) { 299 CHECK_FCT( fd_fifo_post(fd_g_incoming, &msg) ); 300 } else { 301 CHECK_FCT( fd_out_send(&msg, NULL, peer) ); 302 } 293 303 294 304 /* Done */ … … 548 558 { 549 559 TRACE_ENTRY("%p", arg); 560 struct rt_data * rtd = NULL; 550 561 551 562 /* Set the thread name */ … … 563 574 struct msg_hdr * hdr; 564 575 int is_req = 0; 576 struct fd_list * li, *candidates; 577 struct avp * avp; 578 struct rtd_candidate * c; 579 580 /* If we loop'd with some undeleted routing data, destroy it */ 581 if (rtd != NULL) 582 fd_rtd_free(&rtd); 565 583 566 584 /* Test if we were told to stop */ … … 583 601 struct msg * qry; 584 602 char * qry_src = NULL; 603 struct msg_hdr * qry_hdr; 585 604 struct fd_peer * peer = NULL; 586 605 … … 600 619 } 601 620 621 /* We must restore the hop-by-hop id */ 622 CHECK_FCT_DO( fd_msg_hdr(qry, &qry_hdr), goto fatal_error ); 623 hdr->msg_hbhid = qry_hdr->msg_hbhid; 624 602 625 /* Push the message into this peer */ 603 626 CHECK_FCT_DO( fd_out_send(&msg, NULL, peer), goto fatal_error ); … … 607 630 } 608 631 609 /* The message is a request */ 610 TODO("use struct rt_data and fd_msg_rt_get"); 632 /* From that point, the message is a request */ 633 634 /* Get the routing data out of the message if any (in case of re-transmit) */ 635 CHECK_FCT_DO( fd_msg_rt_get ( msg, &rtd ), goto fatal_error ); 636 637 /* If there is no routing data already, let's create it */ 638 if (rtd == NULL) { 639 CHECK_FCT_DO( fd_rtd_init(&rtd), goto fatal_error ); 640 641 /* Add all peers in OPEN state */ 642 CHECK_FCT_DO( pthread_rwlock_wrlock(&fd_g_activ_peers_rw), goto fatal_error ); 643 for (li = fd_g_activ_peers.next; li != &fd_g_activ_peers; li = li->next) { 644 struct fd_peer * p = (struct fd_peer *)li->o; 645 CHECK_FCT_DO( fd_rtd_candidate_add(rtd, p->p_hdr.info.pi_diamid), goto fatal_error); 646 } 647 CHECK_FCT_DO( pthread_rwlock_unlock(&fd_g_activ_peers_rw), goto fatal_error ); 648 649 /* Now let's remove all peers from the Route-Records */ 650 CHECK_FCT_DO( fd_msg_browse(msg, MSG_BRW_FIRST_CHILD, &avp, NULL), goto fatal_error ); 651 while (avp) { 652 struct avp_hdr * ahdr; 653 CHECK_FCT_DO( fd_msg_avp_hdr( avp, &ahdr ), goto fatal_error ); 654 655 if ((ahdr->avp_code == AC_ROUTE_RECORD) && (! (ahdr->avp_flags & AVP_FLAG_VENDOR)) ) { 656 /* Parse this AVP */ 657 CHECK_FCT_DO( fd_msg_parse_dict ( avp, fd_g_config->cnf_dict ), goto fatal_error ); 658 ASSERT( ahdr->avp_value ); 659 /* Remove this value from the list */ 660 fd_rtd_candidate_del(rtd, (char *)ahdr->avp_value->os.data, ahdr->avp_value->os.len); 661 } 662 663 /* Go to next AVP */ 664 CHECK_FCT_DO( fd_msg_browse(avp, MSG_BRW_NEXT, &avp, NULL), goto fatal_error ); 665 } 666 } 667 668 /* Note: we reset the scores and pass the message to the callbacks, maybe we could re-use the saved scores when we have received an error ? */ 669 670 /* Ok, we have our list in rtd now, let's (re)initialize the scores */ 671 fd_rtd_candidate_extract(rtd, &candidates); 672 673 /* Pass the list to registered callbacks (even if it is empty) */ 674 { 675 CHECK_FCT_DO( pthread_rwlock_rdlock( &rt_out_lock ), goto fatal_error ); 676 pthread_cleanup_push( fd_cleanup_rwlock, &rt_out_lock ); 677 678 /* We call the cb by reverse priority order */ 679 for ( li = rt_out_list.prev ; li != &rt_out_list ; li = li->prev ) { 680 struct rt_hdl * rh = (struct rt_hdl *)li; 681 682 TRACE_DEBUG(ANNOYING, "Calling next OUT callback on %p : %p (prio %d)", msg, rh->rt_out_cb, rh->prio); 683 CHECK_FCT_DO( (*rh->rt_out_cb)(rh->cbdata, msg, candidates), 684 { 685 TRACE_DEBUG(INFO, "An OUT routing callback returned an error ! Message discarded."); 686 fd_msg_dump_walk(INFO, msg); 687 fd_msg_free(msg); 688 msg = NULL; 689 break; 690 } ); 691 } 692 693 pthread_cleanup_pop(0); 694 CHECK_FCT_DO( pthread_rwlock_unlock( &rt_out_lock ), goto fatal_error ); 695 696 /* If an error occurred, skip to the next message */ 697 if (!msg) 698 continue; 699 } 700 701 /* Order the candidate peers by score attributed by the callbacks */ 702 CHECK_FCT_DO( fd_rtd_candidate_reorder(candidates), goto fatal_error ); 703 704 /* Save the routing information in the message */ 705 CHECK_FCT_DO( fd_msg_rt_associate ( msg, &rtd ), goto fatal_error ); 706 707 /* Now try sending the message */ 708 for (li = candidates->prev; li != candidates; li = li->prev) { 709 struct fd_peer * peer; 710 711 c = (struct rtd_candidate *) li; 712 713 /* Stop when we have reached the end of valid candidates */ 714 if (c->score < 0) 715 break; 716 717 /* Search for the peer */ 718 CHECK_FCT_DO( fd_peer_getbyid( c->diamid, (void *)&peer ), goto fatal_error ); 719 720 if (peer && (peer->p_hdr.info.runtime.pir_state == STATE_OPEN)) { 721 /* Send to this one */ 722 CHECK_FCT_DO( fd_out_send(&msg, NULL, peer), continue ); 723 /* If the sending was successful */ 724 break; 725 } 726 } 727 728 /* If the message has not been sent, return an error */ 729 if (msg) { 730 TRACE_DEBUG(INFO, "Could not send the following message, replying with UNABLE_TO_DELIVER"); 731 fd_msg_dump_walk(INFO, msg); 732 return_error( msg, "DIAMETER_UNABLE_TO_DELIVER", "No suitable candidate to route the message to", NULL); 733 } 611 734 612 735 /* We're done with this message */ 736 613 737 } while (1); 614 738 … … 619 743 } 620 744 621 745 static pthread_t rt_out = (pthread_t)NULL; 746 static pthread_t rt_in = (pthread_t)NULL; 622 747 623 748 /* Initialize the routing module */ 624 749 int fd_rt_init(void) 625 750 { 626 TODO("Start the routing threads"); 751 CHECK_POSIX( pthread_create( &rt_out, NULL, routing_out_thr, NULL) ); 752 CHECK_POSIX( pthread_create( &rt_in, NULL, routing_in_thr, NULL) ); 627 753 628 754 /* Later: TODO("Set the thresholds for the IN and OUT queues to create more routing threads as needed"); */ 629 return ENOTSUP;755 return 0; 630 756 } 631 757 … … 633 759 int fd_rt_fini(void) 634 760 { 635 TODO("Stop the routing threads"); 636 return ENOTSUP; 637 } 638 639 640 761 CHECK_FCT_DO( fd_thr_term(&rt_in ), /* continue */); 762 CHECK_FCT_DO( fd_thr_term(&rt_out), /* continue */); 763 return 0; 764 } 765 766 767 -
include/freeDiameter/libfreeDiameter.h
r87 r88 1632 1632 void fd_rtd_candidate_del(struct rt_data * rtd, char * peerid, size_t sz /* if !0, peerid does not need to be \0 terminated */); 1633 1633 1634 /* Extract the list of valid candidates, and initialize their scores to 0 */ 1635 void fd_rtd_candidate_extract(struct rt_data * rtd, struct fd_list ** candidates); 1636 1634 1637 /* If a peer returned a protocol error for this message, save it so that we don't try to send it there again */ 1635 1638 int fd_rtd_error_add(struct rt_data * rtd, char * sentto, uint8_t * origin, size_t originsz, uint32_t rcode); 1636 1637 /* Extract the list of valid candidates, and initialize their scores to 0 */1638 void fd_rtd_candidate_extract(struct rt_data * rtd, struct fd_list ** candidates);1639 1639 1640 1640 /* The extracted list items have the following structure: */
Note: See TracChangeset
for help on using the changeset viewer.