Skip to content

Commit

Permalink
[sctp] use send vs sendto for sctp operations
Browse files Browse the repository at this point in the history
some implementations of sendto (FreeBSD) are more picky and will
complain about all the extra data in the sendto(..) when using
connection oriented sockets.

Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
  • Loading branch information
fabbione committed Mar 8, 2019
1 parent da4ee60 commit 44593b2
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 20 deletions.
6 changes: 6 additions & 0 deletions libknet/internals.h
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,12 @@ typedef struct knet_transport_ops {
uint8_t transport_protocol;
transport_acl transport_acl_type;

/*
* connection oriented protocols like SCTP
* prefers send vs sendto on some OSes such as FreeBSD
*/
uint8_t transport_use_send;

uint32_t transport_mtu_overhead;
/*
* transport init must allocate the new transport
Expand Down
12 changes: 8 additions & 4 deletions libknet/threads_heartbeat.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,13 @@ static void _handle_check_each(knet_handle_t knet_h, struct knet_host *dst_host,
}

retry:
len = sendto(dst_link->outsock, outbuf, outlen,
MSG_DONTWAIT | MSG_NOSIGNAL, (struct sockaddr *) &dst_link->dst_addr,
sizeof(struct sockaddr_storage));
if (!transport_get_use_send(knet_h, dst_link->transport)) {
len = sendto(dst_link->outsock, outbuf, outlen,
MSG_DONTWAIT | MSG_NOSIGNAL, (struct sockaddr *) &dst_link->dst_addr,
sizeof(struct sockaddr_storage));
} else {
len = send(dst_link->outsock, outbuf, outlen, MSG_DONTWAIT | MSG_NOSIGNAL);
}
savederrno = errno;

dst_link->ping_last = clock_now;
Expand All @@ -99,7 +103,7 @@ static void _handle_check_each(knet_handle_t knet_h, struct knet_host *dst_host,
switch(err) {
case -1: /* unrecoverable error */
log_debug(knet_h, KNET_SUB_HEARTBEAT,
"Unable to send ping (sock: %d) packet (sendto): %d %s. recorded src ip: %s src port: %s dst ip: %s dst port: %s",
"Unable to send ping (sock: %d) packet (send/sendto): %d %s. recorded src ip: %s src port: %s dst ip: %s dst port: %s",
dst_link->outsock, savederrno, strerror(savederrno),
dst_link->status.src_ipaddr, dst_link->status.src_port,
dst_link->status.dst_ipaddr, dst_link->status.dst_port);
Expand Down
12 changes: 8 additions & 4 deletions libknet/threads_pmtud.c
Original file line number Diff line number Diff line change
Expand Up @@ -172,9 +172,13 @@ static int _handle_check_link_pmtud(knet_handle_t knet_h, struct knet_host *dst_
return -1;
}
retry:
len = sendto(dst_link->outsock, outbuf, data_len,
MSG_DONTWAIT | MSG_NOSIGNAL, (struct sockaddr *) &dst_link->dst_addr,
sizeof(struct sockaddr_storage));
if (!transport_get_use_send(knet_h, dst_link->transport)) {
len = sendto(dst_link->outsock, outbuf, data_len,
MSG_DONTWAIT | MSG_NOSIGNAL, (struct sockaddr *) &dst_link->dst_addr,
sizeof(struct sockaddr_storage));
} else {
len = send(dst_link->outsock, outbuf, data_len, MSG_DONTWAIT | MSG_NOSIGNAL);
}
savederrno = errno;

/*
Expand All @@ -196,7 +200,7 @@ static int _handle_check_link_pmtud(knet_handle_t knet_h, struct knet_host *dst_
err = transport_tx_sock_error(knet_h, dst_link->transport, dst_link->outsock, len, savederrno);
switch(err) {
case -1: /* unrecoverable error */
log_debug(knet_h, KNET_SUB_PMTUD, "Unable to send pmtu packet (sendto): %d %s", savederrno, strerror(savederrno));
log_debug(knet_h, KNET_SUB_PMTUD, "Unable to send pmtu packet (send/sendto): %d %s", savederrno, strerror(savederrno));
pthread_mutex_unlock(&knet_h->tx_mutex);
pthread_mutex_unlock(&knet_h->pmtud_mutex);
dst_link->status.stats.tx_pmtu_errors++;
Expand Down
24 changes: 16 additions & 8 deletions libknet/threads_rx.c
Original file line number Diff line number Diff line change
Expand Up @@ -579,16 +579,20 @@ static void _parse_recv_from_links(knet_handle_t knet_h, int sockfd, const struc
}

retry_pong:
len = sendto(src_link->outsock, outbuf, outlen, MSG_DONTWAIT | MSG_NOSIGNAL,
(struct sockaddr *) &src_link->dst_addr,
sizeof(struct sockaddr_storage));
if (!transport_get_use_send(knet_h, src_link->transport)) {
len = sendto(src_link->outsock, outbuf, outlen, MSG_DONTWAIT | MSG_NOSIGNAL,
(struct sockaddr *) &src_link->dst_addr,
sizeof(struct sockaddr_storage));
} else {
len = send(src_link->outsock, outbuf, outlen, MSG_DONTWAIT | MSG_NOSIGNAL);
}
savederrno = errno;
if (len != outlen) {
err = transport_tx_sock_error(knet_h, src_link->transport, src_link->outsock, len, savederrno);
switch(err) {
case -1: /* unrecoverable error */
log_debug(knet_h, KNET_SUB_RX,
"Unable to send pong reply (sock: %d) packet (sendto): %d %s. recorded src ip: %s src port: %s dst ip: %s dst port: %s",
"Unable to send pong reply (sock: %d) packet (send/sendto): %d %s. recorded src ip: %s src port: %s dst ip: %s dst port: %s",
src_link->outsock, errno, strerror(errno),
src_link->status.src_ipaddr, src_link->status.src_port,
src_link->status.dst_ipaddr, src_link->status.dst_port);
Expand Down Expand Up @@ -672,16 +676,20 @@ static void _parse_recv_from_links(knet_handle_t knet_h, int sockfd, const struc
goto out_pmtud;
}
retry_pmtud:
len = sendto(src_link->outsock, outbuf, outlen, MSG_DONTWAIT | MSG_NOSIGNAL,
(struct sockaddr *) &src_link->dst_addr,
sizeof(struct sockaddr_storage));
if (!transport_get_use_send(knet_h, src_link->transport)) {
len = sendto(src_link->outsock, outbuf, outlen, MSG_DONTWAIT | MSG_NOSIGNAL,
(struct sockaddr *) &src_link->dst_addr,
sizeof(struct sockaddr_storage));
} else {
len = send(src_link->outsock, outbuf, outlen, MSG_DONTWAIT | MSG_NOSIGNAL);
}
savederrno = errno;
if (len != outlen) {
err = transport_tx_sock_error(knet_h, src_link->transport, src_link->outsock, len, savederrno);
switch(err) {
case -1: /* unrecoverable error */
log_debug(knet_h, KNET_SUB_RX,
"Unable to send PMTUd reply (sock: %d) packet (sendto): %d %s. recorded src ip: %s src port: %s dst ip: %s dst port: %s",
"Unable to send PMTUd reply (sock: %d) packet (send/sendto): %d %s. recorded src ip: %s src port: %s dst ip: %s dst port: %s",
src_link->outsock, errno, strerror(errno),
src_link->status.src_ipaddr, src_link->status.src_port,
src_link->status.dst_ipaddr, src_link->status.dst_port);
Expand Down
13 changes: 9 additions & 4 deletions libknet/transports.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,14 @@
#include "transport_sctp.h"
#include "threads_common.h"

#define empty_module -1, -1, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
#define empty_module -1, -1, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },

static knet_transport_ops_t transport_modules_cmd[KNET_MAX_TRANSPORTS] = {
{ "LOOPBACK", KNET_TRANSPORT_LOOPBACK, 1, TRANSPORT_PROTO_LOOPBACK, USE_NO_ACL, KNET_PMTUD_LOOPBACK_OVERHEAD, loopback_transport_init, loopback_transport_free, loopback_transport_link_set_config, loopback_transport_link_clear_config, loopback_transport_link_dyn_connect, loopback_transport_link_get_acl_fd, loopback_transport_rx_sock_error, loopback_transport_tx_sock_error, loopback_transport_rx_is_data },
{ "UDP", KNET_TRANSPORT_UDP, 1, TRANSPORT_PROTO_IP_PROTO, USE_GENERIC_ACL, KNET_PMTUD_UDP_OVERHEAD, udp_transport_init, udp_transport_free, udp_transport_link_set_config, udp_transport_link_clear_config, udp_transport_link_dyn_connect, udp_transport_link_get_acl_fd, udp_transport_rx_sock_error, udp_transport_tx_sock_error, udp_transport_rx_is_data },
{ "LOOPBACK", KNET_TRANSPORT_LOOPBACK, 1, TRANSPORT_PROTO_LOOPBACK, USE_NO_ACL, 0, KNET_PMTUD_LOOPBACK_OVERHEAD, loopback_transport_init, loopback_transport_free, loopback_transport_link_set_config, loopback_transport_link_clear_config, loopback_transport_link_dyn_connect, loopback_transport_link_get_acl_fd, loopback_transport_rx_sock_error, loopback_transport_tx_sock_error, loopback_transport_rx_is_data },
{ "UDP", KNET_TRANSPORT_UDP, 1, TRANSPORT_PROTO_IP_PROTO, USE_GENERIC_ACL, 0, KNET_PMTUD_UDP_OVERHEAD, udp_transport_init, udp_transport_free, udp_transport_link_set_config, udp_transport_link_clear_config, udp_transport_link_dyn_connect, udp_transport_link_get_acl_fd, udp_transport_rx_sock_error, udp_transport_tx_sock_error, udp_transport_rx_is_data },
{ "SCTP", KNET_TRANSPORT_SCTP,
#ifdef HAVE_NETINET_SCTP_H
1, TRANSPORT_PROTO_IP_PROTO, USE_PROTO_ACL, KNET_PMTUD_SCTP_OVERHEAD, sctp_transport_init, sctp_transport_free, sctp_transport_link_set_config, sctp_transport_link_clear_config, sctp_transport_link_dyn_connect, sctp_transport_link_get_acl_fd, sctp_transport_rx_sock_error, sctp_transport_tx_sock_error, sctp_transport_rx_is_data },
1, TRANSPORT_PROTO_IP_PROTO, USE_PROTO_ACL, 1, KNET_PMTUD_SCTP_OVERHEAD, sctp_transport_init, sctp_transport_free, sctp_transport_link_set_config, sctp_transport_link_clear_config, sctp_transport_link_dyn_connect, sctp_transport_link_get_acl_fd, sctp_transport_rx_sock_error, sctp_transport_tx_sock_error, sctp_transport_rx_is_data },
#else
empty_module
#endif
Expand Down Expand Up @@ -133,6 +133,11 @@ int transport_get_acl_type(knet_handle_t knet_h, uint8_t transport)
return transport_modules_cmd[transport].transport_acl_type;
}

int transport_get_use_send(knet_handle_t knet_h, uint8_t transport)
{
return transport_modules_cmd[transport].transport_use_send;
}

/*
* public api
*/
Expand Down
1 change: 1 addition & 0 deletions libknet/transports.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,6 @@ int transport_tx_sock_error(knet_handle_t knet_h, uint8_t transport, int sockfd,
int transport_rx_is_data(knet_handle_t knet_h, uint8_t transport, int sockfd, struct knet_mmsghdr *msg);
int transport_get_proto(knet_handle_t knet_h, uint8_t transport);
int transport_get_acl_type(knet_handle_t knet_h, uint8_t transport);
int transport_get_use_send(knet_handle_t knet_h, uint8_t transport);

#endif

0 comments on commit 44593b2

Please sign in to comment.