Skip to content

Commit

Permalink
Merge branch 'bmk/kernel/20241030/27/gen_udp_blocking_send_on_local/O…
Browse files Browse the repository at this point in the history
…TP-19332' into maint
  • Loading branch information
bmk committed Nov 27, 2024
2 parents 045ec6b + bbcd840 commit a5b8e91
Show file tree
Hide file tree
Showing 3 changed files with 306 additions and 47 deletions.
157 changes: 120 additions & 37 deletions erts/emulator/drivers/common/inet_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -1357,6 +1357,10 @@ static struct erl_drv_entry tcp_inet_driver_entry =


#ifdef HAVE_UDP

/* "IS_UDP": tells the difference between a UDP and an SCTP socket: */
# define IS_UDP(desc)((desc)->sprotocol==IPPROTO_UDP)

static int packet_inet_init(void);
static void packet_inet_stop(ErlDrvData);
static void packet_inet_command(ErlDrvData, char*, ErlDrvSizeT);
Expand Down Expand Up @@ -1407,6 +1411,11 @@ static struct erl_drv_entry udp_inet_driver_entry =
inet_stop_select,
inet_emergency_close
};

#else

# define IS_UDP(desc) 0

#endif

#ifdef HAVE_SCTP
Expand Down Expand Up @@ -14759,18 +14768,44 @@ static void packet_inet_command(ErlDrvData e, char* buf, ErlDrvSizeT len)
long code;
inet_address other;

DDBG(desc,
("INET-DRV-DBG[%d][" SOCKET_FSTR ",%T] "
"packet_inet_command -> entry"
"\r\n",
__LINE__,
desc->s, driver_caller(desc->port)) );

if (! init_caller(&desc->caller, &desc->caller_ref,
desc->port, &buf, &len)) {

DDBG(desc,
("INET-DRV-DBG[%d][" SOCKET_FSTR ",%T] "
"packet_inet_command -> init caller failed"
"\r\n", __LINE__, desc->s, driver_caller(desc->port)) );

driver_failure_posix(desc->port, EINVAL);
return;
}
ptr = buf;

if (!IS_OPEN(desc)) {

DDBG(desc,
("INET-DRV-DBG[%d][" SOCKET_FSTR ",%T] "
"packet_inet_command -> not open"
"\r\n", __LINE__, desc->s, driver_caller(desc->port)) );

inet_reply_error(desc, EINVAL);
return;
}

DDBG(desc,
("INET-DRV-DBG[%d][" SOCKET_FSTR ",%T] "
"packet_inet_command -> data size: %u"
"\r\n",
__LINE__,
desc->s, driver_caller(desc->port), len) );

#ifdef HAVE_SCTP
if (IS_SCTP(desc))
{
Expand Down Expand Up @@ -14813,6 +14848,12 @@ static void packet_inet_command(ErlDrvData e, char* buf, ErlDrvSizeT len)
inet_output_count(desc, data_len);
/* Now do the actual sending. NB: "flags" in "sendmsg" itself are NOT
used: */

DDBG(desc,
("INET-DRV-DBG[%d][" SOCKET_FSTR ",%T] "
"packet_inet_command -> try sendmsg"
"\r\n", __LINE__, desc->s, driver_caller(desc->port)) );

code = sock_sendmsg(desc->s, &mhdr, 0);

goto check_result_code;
Expand Down Expand Up @@ -14845,9 +14886,21 @@ static void packet_inet_command(ErlDrvData e, char* buf, ErlDrvSizeT len)
inet_output_count(desc, len);
if (desc->state & INET_F_ACTIVE) {
/* connected (ignore address) */

DDBG(desc,
("INET-DRV-DBG[%d][" SOCKET_FSTR ",%T] "
"packet_inet_command -> try send (connected)"
"\r\n", __LINE__, desc->s, driver_caller(desc->port)) );

code = sock_send(desc->s, ptr, len, 0);
}
else {

DDBG(desc,
("INET-DRV-DBG[%d][" SOCKET_FSTR ",%T] "
"packet_inet_command -> try sendto"
"\r\n", __LINE__, desc->s, driver_caller(desc->port)) );

code = sock_sendto(desc->s, ptr, len, 0, &other.sa, sz);
}
}
Expand Down Expand Up @@ -14888,6 +14941,12 @@ static void packet_inet_command(ErlDrvData e, char* buf, ErlDrvSizeT len)
mhdr.msg_iovlen = 1;
mhdr.msg_flags = 0;
inet_output_count(desc, len);

DDBG(desc,
("INET-DRV-DBG[%d][" SOCKET_FSTR ",%T] "
"packet_inet_command -> try sendmsg"
"\r\n", __LINE__, desc->s, driver_caller(desc->port)) );

code = sock_sendmsg(desc->s, &mhdr, 0);
#endif
}
Expand All @@ -14896,61 +14955,85 @@ static void packet_inet_command(ErlDrvData e, char* buf, ErlDrvSizeT len)
#ifdef HAVE_SCTP
check_result_code:
/* "code" analysis is the same for both SCTP and UDP above,
* although ERRNO_BLOCK | EINTR never happens for UDP
* although ERRNO_BLOCK | EINTR "never" happens for UDP.
* It *can* actually happen, even though it is difficult
* to provoke (virtualization).
*/
#endif
if (IS_SOCKET_ERROR(code)) {
int err = sock_errno();

DDBG(desc,
("INET-DRV-DBG[%d][" SOCKET_FSTR ",%T] "
"packet_inet_command -> send failed"
"\r\n error: %d (%T)"
"\r\n",
__LINE__,
desc->s, driver_caller(desc->port),
err, error_atom(err)) );

if ((err != ERRNO_BLOCK) && (err != EINTR)) {
inet_reply_error(desc, err);
return;
}
// else if (desc->nonBlockSend) {
else if (IS_NON_BLOCK_SEND(desc)) {
"packet_inet_command -> send failed: "
"\r\n error: %d (%s)"
"\r\n", __LINE__,
desc->s, driver_caller(desc->port), err, errno_str(err)) );

if (IS_UDP(desc)) {

DDBG(desc,
("INET-DRV-DBG[%d][" SOCKET_FSTR ",%T] "
"packet_inet_command -> block|intr when non-block send"
"\r\n",
__LINE__,
desc->s, driver_caller(desc->port)) );

inet_reply_error(desc, err);
return;
}
else {

DDBG(desc,
("INET-DRV-DBG[%d][" SOCKET_FSTR ",%T] "
"packet_inet_command -> block|intr send"
"\r\n",
__LINE__,
desc->s, driver_caller(desc->port)) );
} else {

/* SCTP */
if ((err != ERRNO_BLOCK) && (err != EINTR)) {

inet_reply_error(desc, err);
return;

} else if (IS_NON_BLOCK_SEND(desc)) {

DDBG(desc,
("INET-DRV-DBG[%d][" SOCKET_FSTR ",%T] "
"packet_inet_command -> "
"[sctp] block|intr when non-block send"
"\r\n",
__LINE__,
desc->s, driver_caller(desc->port)) );

inet_reply_error(desc, err);
return;

} else {

DDBG(desc,
("INET-DRV-DBG[%d][" SOCKET_FSTR ",%T] "
"packet_inet_command -> [sctp] block|intr send"
"\r\n",
__LINE__,
desc->s, driver_caller(desc->port)) );

/* XXX if(! INET_IGNORED(INETP(desc))) */
sock_select(desc, (FD_WRITE|FD_CLOSE), 1);
set_busy_port(desc->port, 1);
/* XXX add_multi_timer(... desc->send_timeout, ...); */
inet_reply_caller_ref(desc);
return;
}

/* XXX if(! INET_IGNORED(INETP(desc))) */
sock_select(desc, (FD_WRITE|FD_CLOSE), 1);
set_busy_port(desc->port, 1);
/* XXX add_multi_timer(... desc->send_timeout, ...); */
inet_reply_caller_ref(desc);
return;
}
}
else {

} else {

DDBG(desc,
("INET-DRV-DBG[%d][" SOCKET_FSTR ",%T] "
"packet_inet_command -> ok"
"\r\n", __LINE__, desc->s, driver_caller(desc->port)) );

inet_reply_ok(desc);
return;

}

return_einval:

DDBG(desc,
("INET-DRV-DBG[%d][" SOCKET_FSTR ",%T] "
"packet_inet_command -> einval"
"\r\n", __LINE__, desc->s, driver_caller(desc->port)) );

inet_reply_error(desc, EINVAL);
return;
}
Expand Down
Loading

0 comments on commit a5b8e91

Please sign in to comment.