Changeset 1186:56c36d1007b4 in freeDiameter for libfdcore
- Timestamp:
- Jun 7, 2013, 7:48:34 PM (11 years ago)
- Branch:
- default
- Phase:
- public
- Location:
- libfdcore
- Files:
-
- 14 edited
Legend:
- Unmodified
- Added
- Removed
-
libfdcore/cnxctx.c
r1181 r1186 39 39 #include <net/if.h> 40 40 #include <ifaddrs.h> /* for getifaddrs */ 41 #include <sys/uio.h> /* writev */ 41 42 42 43 /* The maximum size of Diameter message we accept to receive (<= 2^24) to avoid too big mallocs in case of trashed headers */ … … 479 480 } 480 481 482 /* Mark the connection to tell if OOO delivery is permitted (only for SCTP) */ 483 int fd_cnx_unordered_delivery(struct cnxctx * conn, int is_allowed) 484 { 485 CHECK_PARAMS( conn ); 486 conn->cc_sctp_para.unordered = is_allowed; 487 return 0; 488 } 489 481 490 /* Return true if the connection supports unordered delivery of messages */ 482 int fd_cnx_is Multichan(struct cnxctx * conn)491 int fd_cnx_is_unordered_delivery_supported(struct cnxctx * conn) 483 492 { 484 493 CHECK_PARAMS_DO( conn, return 0 ); 485 494 #ifndef DISABLE_SCTP 486 495 if (conn->cc_proto == IPPROTO_SCTP) 487 return (conn->cc_sctp_para.str_ in > 1) || (conn->cc_sctp_para.str_out > 1);496 return (conn->cc_sctp_para.str_out > 1); 488 497 #endif /* DISABLE_SCTP */ 489 498 return 0; … … 531 540 } 532 541 542 static int fd_cnx_may_dtls(struct cnxctx * conn); 543 544 /* Get a short string representing the connection */ 545 int fd_cnx_proto_info(struct cnxctx * conn, char * buf, size_t len) 546 { 547 CHECK_PARAMS( conn ); 548 549 if (fd_cnx_teststate(conn, CC_STATUS_TLS)) { 550 snprintf(buf, len, "%s,%s,soc#%d", IPPROTO_NAME(conn->cc_proto), fd_cnx_may_dtls(conn) ? "DTLS" : "TLS", conn->cc_socket); 551 } else { 552 snprintf(buf, len, "%s,soc#%d", IPPROTO_NAME(conn->cc_proto), conn->cc_socket); 553 } 554 555 return 0; 556 } 557 533 558 /* Retrieve a list of all IP addresses of the local system from the kernel, using getifaddrs */ 534 559 int fd_cnx_get_local_eps(struct fd_list * list) … … 600 625 CHECK_SYS_DO( setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)), /* Also timeout for sending, to avoid waiting forever */ ); 601 626 } 627 628 629 #ifdef GNUTLS_VERSION_300 630 /* The pull_timeout function for gnutls */ 631 static int fd_cnx_s_select (struct cnxctx * conn, unsigned int ms) 632 { 633 fd_set rfds; 634 struct timeval tv; 635 636 FD_ZERO (&rfds); 637 FD_SET (conn->cc_socket, &rfds); 638 639 tv.tv_sec = ms / 1000; 640 tv.tv_usec = (ms * 1000) % 1000000; 641 642 return select (conn->cc_socket + 1, &rfds, NULL, NULL, &tv); 643 } 644 #endif /* GNUTLS_VERSION_300 */ 602 645 603 646 /* A recv-like function, taking a cnxctx object instead of socket as entry. We use it to quickly react to timeouts without traversing GNUTLS wrapper each time */ … … 628 671 } 629 672 630 /* Send */ 631 static ssize_t fd_cnx_s_send(struct cnxctx * conn, void *buffer, size_t length) 673 /* Send, for older GNUTLS */ 674 #ifndef GNUTLS_VERSION_212 675 static ssize_t fd_cnx_s_send(struct cnxctx * conn, const void *buffer, size_t length) 632 676 { 633 677 ssize_t ret = 0; … … 635 679 again: 636 680 ret = send(conn->cc_socket, buffer, length, 0); 681 /* Handle special case of timeout */ 682 if ((ret < 0) && ((errno == EAGAIN) || (errno == EINTR))) { 683 pthread_testcancel(); 684 if (! fd_cnx_teststate(conn, CC_STATUS_CLOSING )) 685 goto again; /* don't care, just ignore */ 686 if (!timedout) { 687 timedout ++; /* allow for one timeout while closing */ 688 goto again; 689 } 690 CHECK_SYS_DO(ret, /* continue */); 691 } 692 693 /* Mark the error */ 694 if (ret <= 0) 695 fd_cnx_markerror(conn); 696 697 return ret; 698 } 699 #endif /* GNUTLS_VERSION_212 */ 700 701 /* Send */ 702 static ssize_t fd_cnx_s_sendv(struct cnxctx * conn, const struct iovec * iov, int iovcnt) 703 { 704 ssize_t ret = 0; 705 int timedout = 0; 706 again: 707 ret = writev(conn->cc_socket, iov, iovcnt); 637 708 /* Handle special case of timeout */ 638 709 if ((ret < 0) && ((errno == EAGAIN) || (errno == EINTR))) { … … 1605 1676 /* Set the push and pull callbacks */ 1606 1677 if (!dtls) { 1678 #ifdef GNUTLS_VERSION_300 1679 GNUTLS_TRACE( gnutls_transport_set_pull_timeout_function( conn->cc_tls_para.session, (void *)fd_cnx_s_select ) ); 1680 #endif /* GNUTLS_VERSION_300 */ 1607 1681 GNUTLS_TRACE( gnutls_transport_set_pull_function(conn->cc_tls_para.session, (void *)fd_cnx_s_recv) ); 1682 #ifndef GNUTLS_VERSION_212 1608 1683 GNUTLS_TRACE( gnutls_transport_set_push_function(conn->cc_tls_para.session, (void *)fd_cnx_s_send) ); 1684 #else /* GNUTLS_VERSION_212 */ 1685 GNUTLS_TRACE( gnutls_transport_set_vec_push_function(conn->cc_tls_para.session, (void *)fd_cnx_s_sendv) ); 1686 #endif /* GNUTLS_VERSION_212 */ 1609 1687 } else { 1610 1688 TODO("DTLS push/pull functions"); … … 1784 1862 CHECK_GNUTLS_DO( ret = fd_tls_send_handle_error(conn, conn->cc_tls_para.session, buf + sent, len - sent), ); 1785 1863 } else { 1786 /* Maybe better to replace this call with sendmsg for atomic sending? */ 1787 CHECK_SYS_DO( ret = fd_cnx_s_send(conn, buf + sent, len - sent), ); 1864 struct iovec iov; 1865 iov.iov_base = buf + sent; 1866 iov.iov_len = len - sent; 1867 CHECK_SYS_DO( ret = fd_cnx_s_sendv(conn, &iov, 1), ); 1788 1868 } 1789 1869 if (ret <= 0) … … 1796 1876 1797 1877 /* Send a message -- this is synchronous -- and we assume it's never called by several threads at the same time (on the same conn), so we don't protect. */ 1798 int fd_cnx_send(struct cnxctx * conn, unsigned char * buf, size_t len , uint32_t flags)1799 { 1800 TRACE_ENTRY("%p %p %zd %x", conn, buf, len, flags);1878 int fd_cnx_send(struct cnxctx * conn, unsigned char * buf, size_t len) 1879 { 1880 TRACE_ENTRY("%p %p %zd", conn, buf, len); 1801 1881 1802 1882 CHECK_PARAMS(conn && (conn->cc_socket > 0) && (! fd_cnx_teststate(conn, CC_STATUS_ERROR)) && buf && len); … … 1812 1892 case IPPROTO_SCTP: { 1813 1893 int dtls = fd_cnx_uses_dtls(conn); 1814 1815 1894 if (!dtls) { 1816 if (flags & FD_CNX_ORDERED) { 1817 /* We send over stream #0 */ 1895 int stream = 0; 1896 if (conn->cc_sctp_para.unordered) { 1897 int limit; 1898 if (fd_cnx_teststate(conn, CC_STATUS_TLS)) 1899 limit = conn->cc_sctp_para.pairs; 1900 else 1901 limit = conn->cc_sctp_para.str_out; 1902 1903 if (limit > 1) { 1904 conn->cc_sctp_para.next += 1; 1905 conn->cc_sctp_para.next %= limit; 1906 stream = conn->cc_sctp_para.next; 1907 } 1908 } 1909 1910 if (stream == 0) { 1911 /* We can use default function, it sends over stream #0 */ 1818 1912 CHECK_FCT( send_simple(conn, buf, len) ); 1819 1913 } else { 1820 /* Default case : no flag specified */ 1821 1822 int another_str = 0; /* do we send over stream #0 ? */ 1823 1824 if ((conn->cc_sctp_para.str_out > 1) && ((!fd_cnx_teststate(conn, CC_STATUS_TLS)) || (conn->cc_sctp_para.pairs > 1))) { 1825 /* Update the id of the stream we will send this message over */ 1826 conn->cc_sctp_para.next += 1; 1827 conn->cc_sctp_para.next %= (fd_cnx_teststate(conn, CC_STATUS_TLS) ? conn->cc_sctp_para.pairs : conn->cc_sctp_para.str_out); 1828 another_str = (conn->cc_sctp_para.next ? 1 : 0); 1829 } 1830 1831 if ( ! another_str ) { 1832 CHECK_FCT( send_simple(conn, buf, len) ); 1914 if (!fd_cnx_teststate(conn, CC_STATUS_TLS)) { 1915 struct iovec iov; 1916 iov.iov_base = buf; 1917 iov.iov_len = len; 1918 1919 CHECK_SYS_DO( fd_sctp_sendstrv(conn, stream, &iov, 1), { fd_cnx_markerror(conn); return ENOTCONN; } ); 1833 1920 } else { 1834 if (!fd_cnx_teststate(conn, CC_STATUS_TLS)) { 1835 CHECK_FCT_DO( fd_sctp_sendstr(conn, conn->cc_sctp_para.next, buf, len), { fd_cnx_markerror(conn); return ENOTCONN; } ); 1836 } else { 1837 /* push the record to the appropriate session */ 1838 ssize_t ret; 1839 size_t sent = 0; 1840 ASSERT(conn->cc_sctp3436_data.array != NULL); 1841 do { 1842 CHECK_GNUTLS_DO( ret = fd_tls_send_handle_error(conn, conn->cc_sctp3436_data.array[conn->cc_sctp_para.next].session, buf + sent, len - sent), ); 1843 if (ret <= 0) 1844 return ENOTCONN; 1845 1846 sent += ret; 1847 } while ( sent < len ); 1848 } 1921 /* push the data to the appropriate session */ 1922 ssize_t ret; 1923 size_t sent = 0; 1924 ASSERT(conn->cc_sctp3436_data.array != NULL); 1925 do { 1926 CHECK_GNUTLS_DO( ret = fd_tls_send_handle_error(conn, conn->cc_sctp3436_data.array[stream].session, buf + sent, len - sent), ); 1927 if (ret <= 0) 1928 return ENOTCONN; 1929 1930 sent += ret; 1931 } while ( sent < len ); 1849 1932 } 1850 1933 } 1851 1934 } else { 1852 1935 /* DTLS */ 1853 /* We signal the push function directly to tell if using stream 0 or round-robin */ 1854 TODO("DTLS send"); 1855 return ENOTSUP; 1936 /* Multistream is handled at lower layer in the push/pull function */ 1937 CHECK_FCT( send_simple(conn, buf, len) ); 1856 1938 } 1857 1939 } -
libfdcore/cnxctx.h
r1181 r1186 75 75 uint16_t pairs; /* max number of pairs ( = min(in, out)) */ 76 76 uint16_t next; /* # of stream the next message will be sent to */ 77 int unordered; /* boolean telling if use of streams > 0 is permitted */ 77 78 } cc_sctp_para; 78 79 … … 118 119 int fd_sctp_get_remote_ep(int sock, struct fd_list * list); 119 120 int fd_sctp_get_str_info( int sock, uint16_t *in, uint16_t *out, sSS *primary ); 120 int fd_sctp_sendstr(struct cnxctx * conn, uint16_t strid, uint8_t * buf, size_t len);121 ssize_t fd_sctp_sendstrv(struct cnxctx * conn, uint16_t strid, const struct iovec *iov, int iovcnt); 121 122 int fd_sctp_recvmeta(struct cnxctx * conn, uint16_t * strid, uint8_t ** buf, size_t * len, int *event); 122 123 -
libfdcore/fdcore-internal.h
r1181 r1186 296 296 297 297 /* Peer out */ 298 int fd_out_send(struct msg ** msg, struct cnxctx * cnx, struct fd_peer * peer , uint32_t flags);298 int fd_out_send(struct msg ** msg, struct cnxctx * cnx, struct fd_peer * peer); 299 299 int fd_out_start(struct fd_peer * peer); 300 300 int fd_out_stop(struct fd_peer * peer); … … 342 342 int fd_cnx_start_clear(struct cnxctx * conn, int loop); 343 343 void fd_cnx_sethostname(struct cnxctx * conn, DiamId_t hn); 344 int fd_cnx_proto_info(struct cnxctx * conn, char * buf, size_t len); 344 345 #define ALGO_HANDSHAKE_DEFAULT 0 /* TLS for TCP, DTLS for SCTP */ 345 346 #define ALGO_HANDSHAKE_3436 1 /* For TLS for SCTP also */ … … 348 349 int fd_cnx_getproto(struct cnxctx * conn); 349 350 int fd_cnx_getTLS(struct cnxctx * conn); 350 int fd_cnx_isMultichan(struct cnxctx * conn); 351 int fd_cnx_is_unordered_delivery_supported(struct cnxctx * conn); 352 int fd_cnx_unordered_delivery(struct cnxctx * conn, int is_allowed); 351 353 int fd_cnx_getcred(struct cnxctx * conn, const gnutls_datum_t **cert_list, unsigned int *cert_list_size); 352 354 int fd_cnx_get_local_eps(struct fd_list * list); … … 355 357 int fd_cnx_receive(struct cnxctx * conn, struct timespec * timeout, unsigned char **buf, size_t * len); 356 358 int fd_cnx_recv_setaltfifo(struct cnxctx * conn, struct fifo * alt_fifo); /* send FDEVP_CNX_MSG_RECV event to the fifo list */ 357 int fd_cnx_send(struct cnxctx * conn, unsigned char * buf, size_t len , uint32_t flags);359 int fd_cnx_send(struct cnxctx * conn, unsigned char * buf, size_t len); 358 360 void fd_cnx_destroy(struct cnxctx * conn); 359 361 #ifdef GNUTLS_VERSION_300 360 362 int fd_tls_verify_credentials_2(gnutls_session_t session); 361 363 #endif /* GNUTLS_VERSION_300 */ 362 363 /* Flags for the fd_cnx_send function : */364 #define FD_CNX_ORDERED (1 << 0) /* All messages sent with this flag set will be delivered in the same order. No guarantee on other messages */365 364 366 365 /* Internal calls of the hook mechanism */ -
libfdcore/hooks.c
r1168 r1186 420 420 } 421 421 CHECK_MALLOC_DO(fd_msg_dump_treeview(&buf, &len, NULL, msg, NULL, 0, 1), break); 422 LOG_N("Connected to '%s', remote capabilities: ", peer ? peer->p_hdr.info.pi_diamid : "<unknown>"); 422 char protobuf[40]; 423 if (peer) { 424 CHECK_FCT_DO(fd_peer_cnx_proto_info(&peer->p_hdr, protobuf, sizeof(protobuf)), break ); 425 } else { 426 protobuf[0] = '-'; 427 protobuf[1] = '\0'; 428 } 429 LOG_N("Connected to '%s' (%s), remote capabilities: ", peer ? peer->p_hdr.info.pi_diamid : "<unknown>", protobuf); 423 430 LOG_SPLIT(FD_LOG_NOTICE, " ", buf?:"<error dumping message>", NULL); 424 431 break; -
libfdcore/p_ce.c
r1181 r1186 633 633 CHECK_FCT_DO( fd_msg_new_answer_from_req ( fd_g_config->cnf_dict, cer, MSGFL_ANSW_ERROR ), goto destroy ); 634 634 CHECK_FCT_DO( fd_msg_rescode_set(*cer, error->pei_errcode, error->pei_message, error->pei_avp, 1 ), goto destroy ); 635 CHECK_FCT_DO( fd_out_send(cer, *recv_cnx, NULL , FD_CNX_ORDERED), goto destroy );635 CHECK_FCT_DO( fd_out_send(cer, *recv_cnx, NULL), goto destroy ); 636 636 637 637 /* And now destroy this connection */ … … 653 653 /* Send CER on the new connection */ 654 654 CHECK_FCT( create_CER(peer, initiator, &cer) ); 655 CHECK_FCT( fd_out_send(&cer, initiator, peer , FD_CNX_ORDERED) );655 CHECK_FCT( fd_out_send(&cer, initiator, peer) ); 656 656 657 657 /* Are we doing an election ? */ … … 708 708 709 709 /* msg now contains an answer message to send back */ 710 CHECK_FCT_DO( fd_out_send(msg, NULL, peer , FD_CNX_ORDERED), /* In case of error the message has already been dumped */ );710 CHECK_FCT_DO( fd_out_send(msg, NULL, peer), /* In case of error the message has already been dumped */ ); 711 711 } 712 712 … … 950 950 fd_hook_call(HOOK_PEER_CONNECT_SUCCESS, msg, peer, NULL, NULL); 951 951 952 CHECK_FCT( fd_out_send(&msg, peer->p_cnxctx, peer , FD_CNX_ORDERED) );952 CHECK_FCT( fd_out_send(&msg, peer->p_cnxctx, peer ) ); 953 953 954 954 /* Handshake if needed */ … … 994 994 CHECK_FCT( fd_p_dw_reopen(peer) ); 995 995 } else { 996 if ((!tls_sync) && (fd_cnx_is Multichan(peer->p_cnxctx))) {996 if ((!tls_sync) && (fd_cnx_is_unordered_delivery_supported(peer->p_cnxctx))) { 997 997 fd_psm_change_state(peer, STATE_OPEN_NEW ); 998 998 /* send DWR */ -
libfdcore/p_cnx.c
r1181 r1186 346 346 } 347 347 } 348 -
libfdcore/p_dp.c
r1127 r1186 118 118 119 119 /* Now send the DPA */ 120 CHECK_FCT( fd_out_send( msg, NULL, peer , FD_CNX_ORDERED) );120 CHECK_FCT( fd_out_send( msg, NULL, peer) ); 121 121 122 122 /* and move to CLOSED */ … … 132 132 133 133 /* Now send the DPA */ 134 CHECK_FCT( fd_out_send( msg, NULL, peer , FD_CNX_ORDERED) );134 CHECK_FCT( fd_out_send( msg, NULL, peer) ); 135 135 } 136 136 } else { … … 202 202 203 203 /* Now send the DPR message */ 204 CHECK_FCT_DO( fd_out_send(&msg, NULL, peer , FD_CNX_ORDERED), /* ignore since we are on timeout anyway */ );204 CHECK_FCT_DO( fd_out_send(&msg, NULL, peer), /* ignore since we are on timeout anyway */ ); 205 205 206 206 return 0; -
libfdcore/p_dw.c
r1127 r1186 83 83 84 84 /* Now send this message */ 85 CHECK_FCT( fd_out_send(&msg, NULL, peer , FD_CNX_ORDERED) );85 CHECK_FCT( fd_out_send(&msg, NULL, peer) ); 86 86 87 87 /* And mark the pending DW */ … … 106 106 CHECK_FCT( fd_msg_rescode_set( *msg, "DIAMETER_SUCCESS", NULL, NULL, 0 ) ); 107 107 CHECK_FCT( fd_msg_add_origin ( *msg, 1 ) ); 108 CHECK_FCT( fd_out_send( msg, peer->p_cnxctx, peer , FD_CNX_ORDERED) );108 CHECK_FCT( fd_out_send( msg, peer->p_cnxctx, peer) ); 109 109 110 110 } else { -
libfdcore/p_out.c
r1119 r1186 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, struct cnxctx * cnx, uint32_t * hbh, struct fd_peer * peer) 40 40 { 41 41 struct msg_hdr * hdr; … … 47 47 struct msg *cpy_for_logs_only; 48 48 49 TRACE_ENTRY("%p % x %p %p %p", msg, flags, cnx, hbh, peer);49 TRACE_ENTRY("%p %p %p %p", msg, cnx, hbh, peer); 50 50 51 51 /* Retrieve the message header */ … … 76 76 77 77 /* Send the message */ 78 CHECK_FCT_DO( ret = fd_cnx_send(cnx, buf, sz , flags), );78 CHECK_FCT_DO( ret = fd_cnx_send(cnx, buf, sz), ); 79 79 out: 80 80 ; … … 128 128 129 129 /* Send the message, log any error */ 130 CHECK_FCT_DO( ret = do_send(&msg, 0,peer->p_cnxctx, &peer->p_hbh, peer),130 CHECK_FCT_DO( ret = do_send(&msg, peer->p_cnxctx, &peer->p_hbh, peer), 131 131 { 132 132 if (msg) { … … 149 149 150 150 /* Wrapper to sending a message either by out thread (peer in OPEN state) or directly; cnx or peer must be provided. Flags are valid only for direct sending, not through thread (unused) */ 151 int fd_out_send(struct msg ** msg, struct cnxctx * cnx, struct fd_peer * peer , uint32_t flags)151 int fd_out_send(struct msg ** msg, struct cnxctx * cnx, struct fd_peer * peer) 152 152 { 153 153 struct msg_hdr * hdr; 154 154 155 TRACE_ENTRY("%p %p %p %x", msg, cnx, peer, flags);155 TRACE_ENTRY("%p %p %p", msg, cnx, peer); 156 156 CHECK_PARAMS( msg && *msg && (cnx || (peer && peer->p_cnxctx))); 157 157 … … 182 182 183 183 /* Do send the message */ 184 CHECK_FCT_DO( ret = do_send(msg, flags,cnx, hbh, peer),184 CHECK_FCT_DO( ret = do_send(msg, cnx, hbh, peer), 185 185 { 186 186 if (msg) { … … 205 205 CHECK_POSIX( pthread_create(&peer->p_outthr, NULL, out_thr, peer) ); 206 206 207 CHECK_FCT( fd_cnx_unordered_delivery(peer->p_cnxctx, 1) ); 208 207 209 return 0; 208 210 } … … 214 216 CHECK_PARAMS( CHECK_PEER(peer) ); 215 217 218 CHECK_FCT( fd_cnx_unordered_delivery(peer->p_cnxctx, 0) ); 219 216 220 CHECK_FCT( fd_thr_term(&peer->p_outthr) ); 217 221 -
libfdcore/p_psm.c
r1181 r1186 72 72 Note about (5) and (6): if the Diameter Identity received in CER or CEA 73 73 does not match the credentials from the certificate presented during 74 DTLS handshake, we may need to specify a path of clean disconnection74 TLS handshake, we may need to specify a path of clean disconnection 75 75 (not blocking the remote peer waiting for something). 76 76 … … 601 601 if (msg == NULL) { 602 602 /* Send the error back to the peer */ 603 CHECK_FCT_DO( ret = fd_out_send(&error, NULL, peer , FD_CNX_ORDERED), );603 CHECK_FCT_DO( ret = fd_out_send(&error, NULL, peer), ); 604 604 if (error) { 605 605 char buf[256]; … … 655 655 656 656 /* Send the answer */ 657 CHECK_FCT_DO( fd_out_send(&msg, peer->p_cnxctx, peer , FD_CNX_ORDERED), break );657 CHECK_FCT_DO( fd_out_send(&msg, peer->p_cnxctx, peer), break ); 658 658 } while (0); 659 659 } else { -
libfdcore/peers.c
r1185 r1186 258 258 } 259 259 260 /* Describe the current connection */ 261 int fd_peer_cnx_proto_info(struct peer_hdr *peer, char * buf, size_t len) 262 { 263 struct fd_peer * p = (struct fd_peer *)peer; 264 TRACE_ENTRY("%p %p %zd", peer, buf, len); 265 CHECK_PARAMS(CHECK_PEER(peer) && buf && len); 266 267 if (p->p_cnxctx) { 268 CHECK_FCT(fd_cnx_proto_info(p->p_cnxctx, buf, len)); 269 } else if (p->p_receiver) { 270 CHECK_FCT(fd_cnx_proto_info(p->p_receiver, buf, len)); 271 } else { 272 snprintf(buf, len, "Not Connected"); 273 } 274 275 return 0; 276 } 277 260 278 /* Return the value of srlist->cnt */ 261 279 int fd_peer_get_load_pending(struct peer_hdr *peer, long * to_receive, long * to_send) … … 512 530 fd_hook_call(HOOK_PEER_CONNECT_FAILED, *cer, NULL, "Received CER with invalid Origin-Host AVP", NULL); 513 531 514 CHECK_FCT( fd_out_send(cer, *cnx, NULL , FD_CNX_ORDERED) );532 CHECK_FCT( fd_out_send(cer, *cnx, NULL) ); 515 533 return EINVAL; 516 534 } -
libfdcore/routing_dispatch.c
r1154 r1186 413 413 CHECK_FCT( fd_fifo_post(fd_g_incoming, pmsg) ); 414 414 } else { 415 CHECK_FCT( fd_out_send(pmsg, NULL, peer , 0) );415 CHECK_FCT( fd_out_send(pmsg, NULL, peer) ); 416 416 } 417 417 … … 887 887 888 888 /* Push the message into this peer */ 889 CHECK_FCT( fd_out_send(&msgptr, NULL, peer , 0) );889 CHECK_FCT( fd_out_send(&msgptr, NULL, peer) ); 890 890 891 891 /* We're done with this answer */ … … 1004 1004 if (fd_peer_getstate(peer) == STATE_OPEN) { 1005 1005 /* Send to this one */ 1006 CHECK_FCT_DO( fd_out_send(&msgptr, NULL, peer , 0), continue );1006 CHECK_FCT_DO( fd_out_send(&msgptr, NULL, peer), continue ); 1007 1007 1008 1008 /* If the sending was successful */ -
libfdcore/sctp.c
r1175 r1186 1080 1080 } 1081 1081 1082 /* Send a buffer over a specified stream */1083 int fd_sctp_sendstr(struct cnxctx * conn, uint16_t strid, uint8_t * buf, size_t len)1082 /* Send a vector over a specified stream */ 1083 ssize_t fd_sctp_sendstrv(struct cnxctx * conn, uint16_t strid, const struct iovec *iov, int iovcnt) 1084 1084 { 1085 1085 struct msghdr mhdr; 1086 struct iovec iov;1087 1086 struct cmsghdr *hdr; 1088 1087 #ifdef OLD_SCTP_SOCKET_API … … 1096 1095 int timedout = 0; 1097 1096 1098 TRACE_ENTRY("%p %hu %p % zd", conn, strid, buf, len);1099 CHECK_PARAMS (conn && buf && len);1097 TRACE_ENTRY("%p %hu %p %d", conn, strid, iov, iovcnt); 1098 CHECK_PARAMS_DO(conn && iov && iovcnt, { errno = EINVAL; return -1; } ); 1100 1099 1101 1100 memset(&mhdr, 0, sizeof(mhdr)); 1102 memset(&iov, 0, sizeof(iov));1103 1101 memset(&anci, 0, sizeof(anci)); 1104 1105 /* IO Vector: message data */1106 iov.iov_base = buf;1107 iov.iov_len = len;1108 1102 1109 1103 /* Anciliary data: specify SCTP stream */ … … 1124 1118 /* We don't use mhdr.msg_name here; it could be used to specify an address different from the primary */ 1125 1119 1126 mhdr.msg_iov = &iov;1127 mhdr.msg_iovlen = 1;1120 mhdr.msg_iov = (struct iovec *)iov; 1121 mhdr.msg_iovlen = iovcnt; 1128 1122 1129 1123 mhdr.msg_control = anci; 1130 1124 mhdr.msg_controllen = sizeof(anci); 1131 1125 1132 TRACE_DEBUG(FULL, "Sending % zdb data on stream %hu of socket %d",len, strid, conn->cc_socket);1126 TRACE_DEBUG(FULL, "Sending %d chunks of data (first:%zdb) on stream %hu of socket %d", iovcnt, iov[0].iov_len, strid, conn->cc_socket); 1133 1127 again: 1134 1128 ret = sendmsg(conn->cc_socket, &mhdr, 0); … … 1144 1138 } 1145 1139 1146 CHECK_SYS( ret ); 1147 ASSERT( ret == len ); /* There should not be partial delivery with sendmsg... */ 1148 1149 return 0; 1140 CHECK_SYS_DO( ret, ); /* for tracing error only */ 1141 1142 return ret; 1150 1143 } 1151 1144 -
libfdcore/sctp3436.c
r1181 r1186 52 52 We also have a demux thread that reads the socket and store received data in the appropriate fifo 53 53 54 We have one gnutls_session per stream pair, and as many streams that read the gnutls records and save incoming data to the target queue.54 We have one gnutls_session per stream pair, and as many threads that read the gnutls records and save incoming data to the target queue. 55 55 56 56 This complexity is required because we cannot read a socket for a given stream only; we can only get the next message and find its stream. 57 57 */ 58 58 59 /* TODO: change this whole wrapper to DTLS which should not require many different threads*/59 /* Note that this mechanism is replaced by DTLS in RFC6733 */ 60 60 61 61 /*************************************************************/ … … 164 164 /*************************************************************/ 165 165 166 #ifdef GNUTLS_VERSION_300 167 /* Check if data is available for gnutls on a given context */ 168 static int sctp3436_pull_timeout(gnutls_transport_ptr_t tr, unsigned int ms) 169 { 170 struct sctp3436_ctx * ctx = (struct sctp3436_ctx *) tr; 171 struct timespec tsstore, *ts = NULL; 172 int ret; 173 174 TRACE_ENTRY("%p %d", tr, ms); 175 176 if (ctx->partial.buf) 177 return 1; /* data is already available for pull */ 178 179 if (ms) { 180 CHECK_SYS_DO( clock_gettime(CLOCK_REALTIME, &tsstore), return -1 ); 181 tsstore.tv_nsec += (long)ms * 1000000; 182 tsstore.tv_sec += tsstore.tv_nsec / 1000000000L; 183 tsstore.tv_nsec %= 1000000000L; 184 ts = &tsstore; 185 } 186 187 ret = fd_fifo_select ( ctx->raw_recv, ts ); 188 if (ret < 0) { 189 errno = -ret; 190 ret = -1; 191 } 192 193 return ret; 194 } 195 #endif /* GNUTLS_VERSION_300 */ 196 166 197 /* Send data over the connection, called by gnutls */ 198 #ifndef GNUTLS_VERSION_212 167 199 static ssize_t sctp3436_push(gnutls_transport_ptr_t tr, const void * data, size_t len) 168 200 { 169 201 struct sctp3436_ctx * ctx = (struct sctp3436_ctx *) tr; 202 struct iovec iov; 170 203 171 204 TRACE_ENTRY("%p %p %zd", tr, data, len); 172 205 CHECK_PARAMS_DO( tr && data, { errno = EINVAL; return -1; } ); 173 206 174 CHECK_FCT_DO( fd_sctp_sendstr(ctx->parent, ctx->strid, (uint8_t *)data, len), return -1 ); 175 176 return len; 177 } 207 iov.iov_base = (void *)data; 208 iov.iov_len = len; 209 210 return fd_sctp_sendstrv(ctx->parent, ctx->strid, &iov, 1); 211 } 212 #else /* GNUTLS_VERSION_212 */ 213 static ssize_t sctp3436_pushv(gnutls_transport_ptr_t tr, const giovec_t * iov, int iovcnt) 214 { 215 struct sctp3436_ctx * ctx = (struct sctp3436_ctx *) tr; 216 217 TRACE_ENTRY("%p %p %d", tr, iov, iovcnt); 218 CHECK_PARAMS_DO( tr && iov, { errno = EINVAL; return -1; } ); 219 220 return fd_sctp_sendstrv(ctx->parent, ctx->strid, (const struct iovec *)iov, iovcnt); 221 } 222 #endif /* GNUTLS_VERSION_212 */ 178 223 179 224 /* Retrieve data received on a stream and already demultiplexed */ … … 238 283 /* starting version 2.12, this call is not needed */ 239 284 GNUTLS_TRACE( gnutls_transport_set_lowat( session, 0 ) ); 285 #else /* GNUTLS_VERSION_300 */ 286 /* but in 3.0 we have to provide the pull_timeout callback */ 287 GNUTLS_TRACE( gnutls_transport_set_pull_timeout_function( session, sctp3436_pull_timeout ) ); 240 288 #endif /* GNUTLS_VERSION_300 */ 241 289 242 290 /* Set the push and pull callbacks */ 243 291 GNUTLS_TRACE( gnutls_transport_set_pull_function(session, sctp3436_pull) ); 292 #ifndef GNUTLS_VERSION_212 244 293 GNUTLS_TRACE( gnutls_transport_set_push_function(session, sctp3436_push) ); 294 #else /* GNUTLS_VERSION_212 */ 295 GNUTLS_TRACE( gnutls_transport_set_vec_push_function(session, sctp3436_pushv) ); 296 #endif /* GNUTLS_VERSION_212 */ 245 297 246 298 return;
Note: See TracChangeset
for help on using the changeset viewer.