Changeset 220:5f2ce627db3c in freeDiameter
- Timestamp:
- Feb 19, 2010, 6:09:43 PM (14 years ago)
- Branch:
- default
- Phase:
- public
- Location:
- freeDiameter
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
freeDiameter/cnxctx.c
r214 r220 122 122 if (sa->sa_family == AF_INET) { 123 123 ((sSA4 *)sa)->sin_port = htons(port); 124 cnx->cc_family = AF_INET; 124 125 } else { 125 126 ((sSA6 *)sa)->sin6_port = htons(port); 127 cnx->cc_family = AF_INET6; 126 128 } 127 129 … … 167 169 CHECK_MALLOC_DO( cnx = fd_cnx_init(0), return NULL ); 168 170 171 if (fd_g_config->cnf_flags.no_ip6) { 172 cnx->cc_family = AF_INET; 173 } else { 174 cnx->cc_family = AF_INET6; /* can create socket for both IP and IPv6 */ 175 } 176 169 177 /* Create the socket */ 170 CHECK_FCT_DO( fd_sctp_create_bind_server( &cnx->cc_socket, ep_list, port ), goto error );178 CHECK_FCT_DO( fd_sctp_create_bind_server( &cnx->cc_socket, cnx->cc_family, ep_list, port ), goto error ); 171 179 172 180 /* Generate the name for the connection object */ … … 229 237 CHECK_MALLOC_DO( cli = fd_cnx_init(1), { shutdown(cli_sock, SHUT_RDWR); close(cli_sock); return NULL; } ); 230 238 cli->cc_socket = cli_sock; 239 cli->cc_family = serv->cc_family; 231 240 cli->cc_proto = serv->cc_proto; 232 241 … … 297 306 298 307 cnx->cc_socket = sock; 308 cnx->cc_family = sa->sa_family; 299 309 cnx->cc_proto = IPPROTO_TCP; 300 310 … … 347 357 348 358 cnx->cc_socket = sock; 359 cnx->cc_family = no_ip6 ? AF_INET : AF_INET6; 349 360 cnx->cc_proto = IPPROTO_SCTP; 350 361 -
freeDiameter/cnxctx.h
r209 r220 46 46 int cc_socket; /* The socket object of the connection -- <=0 if no socket is created */ 47 47 48 int cc_family; /* AF_INET or AF_INET6 (mixed) */ 48 49 int cc_proto; /* IPPROTO_TCP or IPPROTO_SCTP */ 49 50 uint32_t cc_status; /* True if the object is being destroyed: we don't send events anymore */ … … 102 103 #ifndef DISABLE_SCTP 103 104 /* SCTP */ 104 int fd_sctp_create_bind_server( int * sock, struct fd_list * list, uint16_t port );105 int fd_sctp_create_bind_server( int * sock, int family, struct fd_list * list, uint16_t port ); 105 106 int fd_sctp_listen( int sock ); 106 107 int fd_sctp_client( int *sock, int no_ip6, uint16_t port, struct fd_list * list ); 107 int fd_sctp_get_local_ep(int sock, struct fd_list * list);108 int fd_sctp_get_local_ep(int sock, struct fd_list * list); 108 109 int fd_sctp_get_remote_ep(int sock, struct fd_list * list); 109 110 int fd_sctp_get_str_info( int sock, uint16_t *in, uint16_t *out, sSS *primary ); -
freeDiameter/sctp.c
r209 r220 586 586 } 587 587 588 /* Add addresses from a list to an array, with filter on the flags */ 589 static int add_addresses_from_list_mask(uint8_t ** array, size_t * size, int * addr_count, int target_family, uint16_t port, struct fd_list * list, uint32_t mask, uint32_t val) 590 { 591 struct fd_list * li; 592 int to_add4 = 0; 593 int to_add6 = 0; 594 union { 595 uint8_t *buf; 596 sSA4 *sin; 597 sSA6 *sin6; 598 } ptr; 599 size_t sz; 600 601 /* First, count the number of addresses to add */ 602 for (li = list->next; li != list; li = li->next) { 603 struct fd_endpoint * ep = (struct fd_endpoint *) li; 604 605 /* Do the flag match ? */ 606 if ((val & mask) != (ep->flags & mask)) 607 continue; 608 609 if (ep->sa.sa_family == AF_INET) { 610 to_add4 ++; 611 } else { 612 to_add6 ++; 613 } 614 } 615 616 if ((to_add4 + to_add6) == 0) 617 return 0; /* nothing to do */ 618 619 /* The size to add */ 620 if (target_family == AF_INET) { 621 sz = to_add4 * sizeof(sSA4); 622 } else { 623 #ifndef SCTP_USE_MAPPED_ADDRESSES 624 sz = (to_add4 * sizeof(sSA4)) + (to_add6 * sizeof(sSA6)); 625 #else /* SCTP_USE_MAPPED_ADDRESSES */ 626 sz = (to_add4 + to_add6) * sizeof(sSA6); 627 #endif /* SCTP_USE_MAPPED_ADDRESSES */ 628 } 629 630 /* Now, (re)alloc the array to store the new addresses */ 631 CHECK_MALLOC( *array = realloc(*array, *size + sz) ); 632 633 /* Finally, add the addresses */ 634 for (li = list->next; li != list; li = li->next) { 635 struct fd_endpoint * ep = (struct fd_endpoint *) li; 636 637 /* Skip v6 addresses for v4 socket */ 638 if ((target_family == AF_INET) && (ep->sa.sa_family == AF_INET6)) 639 continue; 640 641 /* Are the flags matching ? */ 642 if ((val & mask) != (ep->flags & mask)) 643 continue; 644 645 /* Size of the new SA we are adding (array may contain a mix of sockaddr_in and sockaddr_in6) */ 646 #ifndef SCTP_USE_MAPPED_ADDRESSES 647 if (ep->sa.sa_family == AF_INET6) 648 #else /* SCTP_USE_MAPPED_ADDRESSES */ 649 if (target_family == AF_INET6) { 650 #endif /* SCTP_USE_MAPPED_ADDRESSES */ 651 sz = sizeof(sSA6); 652 else 653 sz = sizeof(sSA4); 654 655 /* Place where we add the new address */ 656 ptr.buf = *array + *size; /* place of the new SA */ 657 658 /* Update other information */ 659 *size += sz; 660 *addr_count += 1; 661 662 /* And write the addr in the buffer */ 663 if (sz == sizeof(sSA4)) { 664 memcpy(ptr.buf, &ep->sin, sz); 665 ptr.sin->sin_port = port; 666 } else { 667 if (ep->sa.sa_family == AF_INET) { /* We must map the address */ 668 memset(ptr.buf, 0, sz); 669 ptr.sin6->sin6_family = AF_INET6; 670 IN6_ADDR_V4MAP( &ptr.sin6->sin6_addr.s6_addr, ep->sin.sin_addr.s_addr ); 671 } else { 672 memcpy(ptr.sin6, &ep->sin6, sz); 673 } 674 ptr.sin6->sin6_port = port; 675 } 676 } 677 678 return 0; 679 } 680 588 681 /* Create a socket server and bind it according to daemon s configuration */ 589 int fd_sctp_create_bind_server( int * sock, struct fd_list * list, uint16_t port )682 int fd_sctp_create_bind_server( int * sock, int family, struct fd_list * list, uint16_t port ) 590 683 { 591 int family;592 684 int bind_default; 593 685 594 TRACE_ENTRY("%p % p %hu", sock, list, port);686 TRACE_ENTRY("%p %i %p %hu", sock, family, list, port); 595 687 CHECK_PARAMS(sock); 596 597 if (fd_g_config->cnf_flags.no_ip6) {598 family = AF_INET;599 } else {600 family = AF_INET6; /* can create socket for both IP and IPv6 */601 }602 688 603 689 /* Create the socket */ … … 633 719 /* Explicit endpoints to bind to from config */ 634 720 635 union { 636 sSA * sa; 637 sSA4 *sin; 638 sSA6 *sin6; 639 uint8_t *buf; 640 } ptr; 641 union { 642 sSA * sa; 643 uint8_t * buf; 644 } sar; 645 int count = 0; /* number of sock addr in sar array */ 646 size_t offset = 0; 647 struct fd_list * li; 648 649 sar.buf = NULL; 650 651 /* Create a flat array from the list of configured addresses */ 652 for (li = list->next; li != list; li = li->next) { 653 struct fd_endpoint * ep = (struct fd_endpoint *)li; 654 size_t sz = 0; 655 656 if (! (ep->flags & EP_FL_CONF)) 657 continue; 658 659 count++; 660 661 /* Size of the new SA we are adding (sar may contain a mix of sockaddr_in and sockaddr_in6) */ 662 #ifndef SCTP_USE_MAPPED_ADDRESSES 663 if (ep->sa.sa_family == AF_INET6) 664 #else /* SCTP_USE_MAPPED_ADDRESSES */ 665 if (family == AF_INET6) 666 #endif /* SCTP_USE_MAPPED_ADDRESSES */ 667 sz = sizeof(sSA6); 668 else 669 sz = sizeof(sSA4); 670 671 /* augment sar to contain the additional info */ 672 CHECK_MALLOC( sar.buf = realloc(sar.buf, offset + sz) ); 673 674 ptr.buf = sar.buf + offset; /* place of the new SA */ 675 offset += sz; /* update to end of sar */ 676 677 if (sz == sizeof(sSA4)) { 678 memcpy(ptr.buf, &ep->sin, sz); 679 ptr.sin->sin_port = htons(port); 680 } else { 681 if (ep->sa.sa_family == AF_INET) { /* We must map the address */ 682 memset(ptr.buf, 0, sz); 683 ptr.sin6->sin6_family = AF_INET6; 684 IN6_ADDR_V4MAP( &ptr.sin6->sin6_addr.s6_addr, ep->sin.sin_addr.s_addr ); 685 } else { 686 memcpy(ptr.sin6, &ep->sin6, sz); 687 } 688 ptr.sin6->sin6_port = htons(port); 689 } 690 } 721 sSA * sar = NULL; /* array of addresses */ 722 size_t sz = 0; /* size of the array */ 723 int count = 0; /* number of sock addr in the array */ 724 725 /* Create the array of configured addresses */ 726 CHECK_FCT( add_addresses_from_list_mask((void *)&sar, &sz, &count, family, port, list, EP_FL_CONF, EP_FL_CONF) ); 691 727 692 728 if (!count) { … … 697 733 698 734 if (TRACE_BOOL(SCTP_LEVEL)) { 735 union { 736 sSA *sa; 737 uint8_t *buf; 738 } ptr; 699 739 int i; 700 ptr. buf = sar.buf;740 ptr.sa = sar; 701 741 fd_log_debug("Calling sctp_bindx with the following address array:\n"); 702 742 for (i = 0; i < count; i++) { … … 707 747 708 748 /* Bind to this array */ 709 CHECK_SYS( sctp_bindx(*sock, sar .sa, count, SCTP_BINDX_ADD_ADDR) );749 CHECK_SYS( sctp_bindx(*sock, sar, count, SCTP_BINDX_ADD_ADDR) ); 710 750 711 751 /* We don't need sar anymore */ 712 free(sar .buf);752 free(sar); 713 753 } 714 754 … … 745 785 } 746 786 747 /* Add addresses from the list that match the flags to the array */748 static int add_addresses_from_list_mask(uint8_t ** array, int * count, size_t * offset, uint16_t port, struct fd_list * list, uint32_t mask, uint32_t val)749 {750 size_t sz;751 struct fd_list * li;752 union {753 uint8_t *buf;754 sSA4 *sin;755 sSA6 *sin6;756 } ptr;757 758 for (li = list->next; li != list; li = li->next) {759 struct fd_endpoint * ep = (struct fd_endpoint *) li;760 761 /* Do the flag match ? */762 if ((val & mask) != (ep->flags & mask))763 continue;764 765 /* We add this endpoint at the end of array */766 (*count)++;767 768 /* Size of the new SA we are adding (array may contain a mix of sockaddr_in and sockaddr_in6) */769 #ifndef SCTP_USE_MAPPED_ADDRESSES770 if (ep->sa.sa_family == AF_INET6)771 #else /* SCTP_USE_MAPPED_ADDRESSES */772 if (family == AF_INET6)773 #endif /* SCTP_USE_MAPPED_ADDRESSES */774 sz = sizeof(sSA6);775 else776 sz = sizeof(sSA4);777 778 /* augment array to contain the additional info */779 CHECK_MALLOC( *array = realloc(*array, (*offset) + sz) );780 781 ptr.buf = *array + *offset; /* place of the new SA */782 (*offset) += sz; /* update to end of sar */783 784 if (sz == sizeof(sSA4)) {785 memcpy(ptr.buf, &ep->sin, sz);786 ptr.sin->sin_port = port;787 } else {788 if (ep->sa.sa_family == AF_INET) { /* We must map the address */789 memset(ptr.buf, 0, sz);790 ptr.sin6->sin6_family = AF_INET6;791 IN6_ADDR_V4MAP( &ptr.sin6->sin6_addr.s6_addr, ep->sin.sin_addr.s_addr );792 } else {793 memcpy(ptr.sin6, &ep->sin6, sz);794 }795 ptr.sin6->sin6_port = port;796 }797 }798 799 return 0;800 }801 802 787 /* Create a client socket and connect to remote server */ 803 788 int fd_sctp_client( int *sock, int no_ip6, uint16_t port, struct fd_list * list ) 804 789 { 805 790 int family; 806 int count = 0;807 size_t offset = 0;808 791 union { 809 792 uint8_t *buf; 810 793 sSA *sa; 811 794 } sar; 795 size_t size = 0; 796 int count = 0; 812 797 int ret; 813 798 … … 833 818 834 819 /* Create the array of addresses, add first the configured addresses, then the discovered, then the other ones */ 835 CHECK_FCT_DO( ret = add_addresses_from_list_mask(&sar.buf, & count, &offset, htons(port), list, EP_FL_CONF,EP_FL_CONF ), goto fail );836 CHECK_FCT_DO( ret = add_addresses_from_list_mask(&sar.buf, & count, &offset, htons(port), list, EP_FL_CONF | EP_FL_DISC, EP_FL_DISC ), goto fail );837 CHECK_FCT_DO( ret = add_addresses_from_list_mask(&sar.buf, & count, &offset, htons(port), list, EP_FL_CONF | EP_FL_DISC, 0 ), goto fail );820 CHECK_FCT_DO( ret = add_addresses_from_list_mask(&sar.buf, &size, &count, family, htons(port), list, EP_FL_CONF, EP_FL_CONF ), goto fail ); 821 CHECK_FCT_DO( ret = add_addresses_from_list_mask(&sar.buf, &size, &count, family, htons(port), list, EP_FL_CONF | EP_FL_DISC, EP_FL_DISC ), goto fail ); 822 CHECK_FCT_DO( ret = add_addresses_from_list_mask(&sar.buf, &size, &count, family, htons(port), list, EP_FL_CONF | EP_FL_DISC, 0 ), goto fail ); 838 823 839 824 /* Try connecting */ … … 860 845 CHECK_SYS_DO( sctp_connectx(*sock, sar.sa, count), { ret = errno; goto fail; } ); 861 846 #endif /* SCTP_CONNECTX_4_ARGS */ 862 863 /*****************864 BUG : received "EINVAL" at reconnection attempt... Should probably filter what is in that list !865 *****************/866 847 867 848 free(sar.buf); sar.buf = NULL; … … 937 918 } ptr; 938 919 939 sSA * data ;920 sSA * data = NULL; 940 921 int count; 941 922 … … 954 935 default: 955 936 TRACE_DEBUG(INFO, "Unkown address family returned in sctp_getladdrs: %d", ptr.sa->sa_family); 937 TRACE_DEBUG_BUFFER(NONE, "DEBUG: Parsed data : [", data, ptr.buf - (uint8_t *)data, "]" ); 938 TRACE_DEBUG(NONE, "DEBUG: Remaining %d addresses to parse in :", count) 939 TRACE_DEBUG_BUFFER(NONE, "DEBUG: Unable to parse [", ptr.buf, count * sizeof(sSA), "]" ); 940 goto stop; 956 941 } 957 942 … … 960 945 count --; 961 946 } 962 947 stop: 963 948 /* Free the list */ 964 949 sctp_freeladdrs(data); … … 994 979 ptr.sa = data; 995 980 996 TRACE_DEBUG(NONE, "DEBUG: count = %d", count);997 TRACE_DEBUG_BUFFER(NONE, "DEBUG: data = ", ptr.buf, count * sizeof(sSA4), "" );998 999 981 while (count) { 1000 982 socklen_t sl; … … 1004 986 default: 1005 987 TRACE_DEBUG(INFO, "Unkown address family returned in sctp_getpaddrs: %d, skip", ptr.sa->sa_family); 1006 goto next; 988 TRACE_DEBUG_BUFFER(NONE, "DEBUG: Parsed data : [", data, ptr.buf - (uint8_t *)data, "]" ); 989 TRACE_DEBUG(NONE, "DEBUG: Remaining %d addresses to parse in :", count) 990 TRACE_DEBUG_BUFFER(NONE, "DEBUG: Unable to parse [", ptr.buf, count * sizeof(sSA), "]" ); 991 goto stop; 1007 992 } 1008 993 … … 1011 996 count --; 1012 997 } 1013 next:998 stop: 1014 999 /* Free the list */ 1015 1000 sctp_freepaddrs(data);
Note: See TracChangeset
for help on using the changeset viewer.