diff options
Diffstat (limited to 'erts/emulator/drivers/common/inet_drv.c')
-rw-r--r-- | erts/emulator/drivers/common/inet_drv.c | 657 |
1 files changed, 394 insertions, 263 deletions
diff --git a/erts/emulator/drivers/common/inet_drv.c b/erts/emulator/drivers/common/inet_drv.c index 2ef452fa01..49db7077de 100644 --- a/erts/emulator/drivers/common/inet_drv.c +++ b/erts/emulator/drivers/common/inet_drv.c @@ -22,9 +22,10 @@ #include "config.h" #endif + /* If we HAVE_SCTP_H and Solaris, we need to define the following in - order to get SCTP working: -*/ + * order to get SCTP working: + */ #if (defined(HAVE_SCTP_H) && defined(__sun) && defined(__SVR4)) #define SOLARIS10 1 /* WARNING: This is not quite correct, it may also be Solaris 11! */ @@ -81,6 +82,32 @@ /* All platforms fail on malloc errors. */ #define FATAL_MALLOC +/* The linux kernel sctp include files have an alignment bug + that causes warnings of this type to appear: + + drivers/common/inet_drv.c:3196:47: error: taking address of packed member of 'struct sctp_paddr_change' may result in an unaligned pointer value [-Werror=address-of-packed-member] + 3196 | i = load_inet_get_address(spec, i, desc, &sptr->spc_aaddr); + + So we need to suppress those, without disabling all warning + diagnostics of that type. + + See https://lore.kernel.org/patchwork/patch/1108122/ for the + patch that fixes this bug. In a few years we should be able to + remove this suppression. */ +#ifdef HAVE_GCC_DIAG_IGNORE_WADDRESS_OF_PACKED_MEMBER +#define PUSH_SUPPRESS_ADDRESS_OF_PACKED_MEMBER() \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Waddress-of-packed-member\"") \ + do { } while(0) +#define POP_SUPPRESS_ADDRESS_OF_PACKED_MEMBER() \ + _Pragma("GCC diagnostic pop") \ + do { } while(0) +#else +#define PUSH_SUPPRESS_ADDRESS_OF_PACKED_MEMBER() \ + do { } while(0) +#define POP_SUPPRESS_ADDRESS_OF_PACKED_MEMBER() \ + do { } while(0) +#endif #include "erl_driver.h" @@ -578,8 +605,8 @@ static int my_strncasecmp(const char *s1, const char *s2, size_t n) (d)->event_mask = (onoff) ? \ ((d)->event_mask | (flags)) : \ ((d)->event_mask & ~(flags)); \ - DEBUGF(("(%s / %d) sock_select(%ld): flags=%02X, onoff=%d, event_mask=%02lX\r\n", \ - __FILE__, __LINE__, (long) (d)->port, (flags), (onoff), (unsigned long) (d)->event_mask)); \ + DEBUGF(("(%s / %d) sock_select(%p): flags=%02X, onoff=%d, event_mask=%02lX\r\n", \ + __FILE__, __LINE__, (d)->port, (flags), (onoff), (unsigned long) (d)->event_mask)); \ inet_driver_select((d)->port, (ErlDrvEvent)(long)(d)->event, (flags), (onoff)); \ } while(0) @@ -591,21 +618,15 @@ static int my_strncasecmp(const char *s1, const char *s2, size_t n) #ifdef HAVE_SOCKLEN_T # define SOCKLEN_T socklen_t +#elif defined(__WIN32__) +# define SOCKLEN_T int #else +# warning "Non-Windows OS without type 'socklen_t'" # define SOCKLEN_T size_t #endif #include "packet_parser.h" -#define get_int24(s) ((((unsigned char*) (s))[0] << 16) | \ - (((unsigned char*) (s))[1] << 8) | \ - (((unsigned char*) (s))[2])) - -#define get_little_int32(s) ((((unsigned char*) (s))[3] << 24) | \ - (((unsigned char*) (s))[2] << 16) | \ - (((unsigned char*) (s))[1] << 8) | \ - (((unsigned char*) (s))[0])) - #if defined(HAVE_SYS_UN_H) || defined(SO_BINDTODEVICE) /* strnlen doesn't exist everywhere */ @@ -1113,8 +1134,8 @@ typedef struct { inet_address* peer_ptr; /* fake peername or NULL */ inet_address* name_ptr; /* fake sockname or NULL */ - SOCKLEN_T peer_addr_len; /* fake peername size */ - SOCKLEN_T name_addr_len; /* fake sockname size */ + unsigned int peer_addr_len; /* fake peername size */ + unsigned int name_addr_len; /* fake sockname size */ int bufsz; /* minimum buffer constraint */ unsigned int hsz; /* the list header size, -1 is large !!! */ @@ -1151,9 +1172,24 @@ typedef struct { #define TCP_MAX_PACKET_SIZE 0x4000000 /* 64 M */ -#define MAX_VSIZE 16 /* Max number of entries allowed in an I/O - * vector sock_sendv(). - */ +/* Max number of entries allowed in an I/O vector sock_sendv(). */ +#if defined(__WIN32__) +/* + * Windows 95, 98, and ME is limited to 16, but we do not + * support those. Documentation unfortunately does not say + * anything about newer windows, so we guess 1024 which + * seems to be what most systems use... + */ +#define MAX_VSIZE 1024 +#elif !defined(NO_SYSCONF) +static int iov_max; +#define MAX_VSIZE iov_max +#elif defined(IOV_MAX) +#define MAX_VSIZE IOV_MAX +#else +/* POSIX require at least 16 */ +#define MAX_VSIZE 16 +#endif static int tcp_inet_init(void); static void tcp_inet_stop(ErlDrvData); @@ -2104,7 +2140,7 @@ static int enq_async_w_tmo(inet_descriptor* desc, char* buf, int req, unsigned t if ((opp = desc->oph) == NULL) /* queue empty */ opp = desc->oph = desc->opt = desc->op_queue; else if (desc->oph == desc->opt) { /* queue full */ - DEBUGF(("enq(%ld): queue full\r\n", (long)desc->port)); + DEBUGF(("enq(%p): queue full\r\n", desc->port)); return -1; } @@ -2116,8 +2152,8 @@ static int enq_async_w_tmo(inet_descriptor* desc, char* buf, int req, unsigned t memcpy(&(opp->monitor),monitorp,sizeof(ErlDrvMonitor)); } - DEBUGF(("enq(%ld): %d %ld %d\r\n", - (long) desc->port, opp->id, opp->caller, opp->req)); + DEBUGF(("enq(%p): %d %ld %d\r\n", + desc->port, opp->id, opp->caller, opp->req)); opp++; if (opp >= desc->op_queue + INET_MAX_ASYNC) @@ -2141,7 +2177,7 @@ static int deq_async_w_tmo(inet_descriptor* desc, int* ap, ErlDrvTermData* cp, inet_async_op* opp; if ((opp = desc->opt) == NULL) { /* queue empty */ - DEBUGF(("deq(%ld): queue empty\r\n", (long)desc->port)); + DEBUGF(("deq(%p): queue empty\r\n", desc->port)); return -1; } *ap = opp->id; @@ -2154,8 +2190,8 @@ static int deq_async_w_tmo(inet_descriptor* desc, int* ap, ErlDrvTermData* cp, memcpy(monitorp,&(opp->monitor),sizeof(ErlDrvMonitor)); } - DEBUGF(("deq(%ld): %d %ld %d\r\n", - (long)desc->port, opp->id, opp->caller, opp->req)); + DEBUGF(("deq(%p): %d %ld %d\r\n", + desc->port, opp->id, opp->caller, opp->req)); opp++; if (opp >= desc->op_queue + INET_MAX_ASYNC) @@ -2377,7 +2413,8 @@ static int inet_port_data(inet_descriptor* desc, const char* buf, int len) { unsigned int hsz = desc->hsz; - DEBUGF(("inet_port_data(%ld): len = %d\r\n", (long)desc->port, len)); + DEBUGF(("inet_port_data(%p): len = %d\r\n", + desc->port, len)); if ((desc->mode == INET_MODE_LIST) || (hsz > len)) return driver_output2(desc->port, (char*)buf, len, NULL, 0); @@ -2395,8 +2432,8 @@ inet_port_binary_data(inet_descriptor* desc, ErlDrvBinary* bin, int offs, int le { unsigned int hsz = desc->hsz; - DEBUGF(("inet_port_binary_data(%ld): offs=%d, len = %d\r\n", - (long)desc->port, offs, len)); + DEBUGF(("inet_port_binary_data(%p): offs=%d, len = %d\r\n", + desc->port, offs, len)); if ((desc->mode == INET_MODE_LIST) || (hsz > len)) return driver_output2(desc->port, bin->orig_bytes+offs, len, NULL, 0); @@ -2574,16 +2611,18 @@ http_request_inetdrv(void* arg, const http_atom_t* meth, const char* meth_ptr, } static int -http_header_inetdrv(void* arg, const http_atom_t* name, const char* name_ptr, - int name_len, const char* value_ptr, int value_len) +http_header_inetdrv(void* arg, const http_atom_t* name, + const char* name_ptr, int name_len, + const char* oname_ptr, int oname_len, + const char* value_ptr, int value_len) { tcp_descriptor* desc = (tcp_descriptor*) arg; int i = 0; - ErlDrvTermData spec[26]; + ErlDrvTermData spec[27]; ErlDrvTermData caller = ERL_DRV_NIL; if (desc->inet.active == INET_PASSIVE) { - /* {inet_async,S,Ref,{ok,{http_header,Bit,Name,IValue,Value}} */ + /* {inet_async,S,Ref,{ok,{http_header,Bit,Name,Oname,Value}} */ int req; int aid; @@ -2596,7 +2635,7 @@ http_header_inetdrv(void* arg, const http_atom_t* name, const char* name_ptr, i = LOAD_ATOM(spec, i, am_ok); } else { - /* {http, S, {http_header,Bit,Name,IValue,Value}} */ + /* {http, S, {http_header,Bit,Name,Oname,Value}} */ i = LOAD_ATOM(spec, i, am_http); i = LOAD_PORT(spec, i, desc->inet.dport); } @@ -2610,19 +2649,19 @@ http_header_inetdrv(void* arg, const http_atom_t* name, const char* name_ptr, i = LOAD_INT(spec, i, 0); i = http_load_string(desc, spec, i, name_ptr, name_len); } - i = LOAD_ATOM(spec, i, am_undefined); + i = http_load_string(desc, spec, i, oname_ptr, oname_len); i = http_load_string(desc, spec, i, value_ptr, value_len); i = LOAD_TUPLE(spec, i, 5); if (desc->inet.active == INET_PASSIVE) { i = LOAD_TUPLE(spec, i, 2); i = LOAD_TUPLE(spec, i, 4); - ASSERT(i <= 26); + ASSERT(i <= 27); return erl_drv_send_term(desc->inet.dport, caller, spec, i); } else { i = LOAD_TUPLE(spec, i, 3); - ASSERT(i <= 26); + ASSERT(i <= 27); return erl_drv_output_term(desc->inet.dport, spec, i); } } @@ -2788,7 +2827,8 @@ static int inet_async_data(inet_descriptor* desc, const char* buf, int len) int aid; int i = 0; - DEBUGF(("inet_async_data(%ld): len = %d\r\n", (long)desc->port, len)); + DEBUGF(("inet_async_data(%p): len = %d\r\n", + desc->port, len)); if (deq_async(desc, &aid, &caller, &req) < 0) return -1; @@ -3170,7 +3210,9 @@ static int sctp_parse_async_event ASSERT(sptr->spc_length <= sz); /* No buffer overrun */ i = LOAD_ATOM (spec, i, am_sctp_paddr_change); + PUSH_SUPPRESS_ADDRESS_OF_PACKED_MEMBER(); i = load_inet_get_address(spec, i, desc, &sptr->spc_aaddr); + POP_SUPPRESS_ADDRESS_OF_PACKED_MEMBER(); switch (sptr->spc_state) { @@ -3481,8 +3523,8 @@ inet_async_binary_data int ok_pos; #endif - DEBUGF(("inet_async_binary_data(%ld): offs=%d, len=%d\r\n", - (long)desc->port, offs, len)); + DEBUGF(("inet_async_binary_data(%p): offs=%d, len=%d\r\n", + desc->port, offs, len)); if (deq_async(desc, &aid, &caller, &req) < 0) return -1; @@ -3588,7 +3630,8 @@ static int tcp_message(inet_descriptor* desc, const char* buf, int len) ErlDrvTermData spec[20]; int i = 0; - DEBUGF(("tcp_message(%ld): len = %d\r\n", (long)desc->port, len)); + DEBUGF(("tcp_message(%p): len = %d\r\n", + desc->port, len)); /* XXX fprintf(stderr,"tcp_message send.\r\n"); */ i = LOAD_ATOM(spec, i, am_tcp); @@ -3626,7 +3669,8 @@ tcp_binary_message(inet_descriptor* desc, ErlDrvBinary* bin, int offs, int len) ErlDrvTermData spec[20]; int i = 0; - DEBUGF(("tcp_binary_message(%ld): len = %d\r\n", (long)desc->port, len)); + DEBUGF(("tcp_binary_message(%p): len = %d\r\n", + desc->port, len)); i = LOAD_ATOM(spec, i, am_tcp); i = LOAD_PORT(spec, i, desc->dport); @@ -3656,7 +3700,7 @@ static int tcp_closed_message(tcp_descriptor* desc) ErlDrvTermData spec[6]; int i = 0; - DEBUGF(("tcp_closed_message(%ld):\r\n", (long)desc->inet.port)); + DEBUGF(("tcp_closed_message(%p):\r\n", desc->inet.port)); if (!(desc->tcp_add_flags & TCP_ADDF_CLOSE_SENT)) { desc->tcp_add_flags |= TCP_ADDF_CLOSE_SENT; @@ -3678,7 +3722,8 @@ static int tcp_error_message(tcp_descriptor* desc, int err) ErlDrvTermData am_err = error_atom(err); int i = 0; - DEBUGF(("tcp_error_message(%ld): %d\r\n", (long)desc->inet.port, err)); + DEBUGF(("tcp_error_message(%p): %d\r\n", + desc->inet.port, err)); i = LOAD_ATOM(spec, i, am_tcp_error); i = LOAD_PORT(spec, i, desc->inet.dport); @@ -3708,8 +3753,8 @@ static int packet_binary_message(inet_descriptor* desc, int alen; char* data = bin->orig_bytes+offs; - DEBUGF(("packet_binary_message(%ld): len = %d\r\n", - (long)desc->port, len)); + DEBUGF(("packet_binary_message(%p): len = %d\r\n", + desc->port, len)); # ifdef HAVE_SCTP i = LOAD_ATOM(spec, i, IS_SCTP(desc) ? am_sctp : am_udp); /* UDP|SCTP */ # else @@ -3808,7 +3853,7 @@ static int packet_binary_message(inet_descriptor* desc, ErlDrvTermData spec[6]; int i = 0; - DEBUGF(("packet_passive_message(%ld):\r\n", (long)desc->port)); + DEBUGF(("packet_passive_message(%p):\r\n", desc->port)); #if !defined(HAVE_UDP) && !defined(HAVE_SCTP) i = LOAD_ATOM(spec, i, am_tcp_passive); @@ -3840,8 +3885,8 @@ static int packet_error_message(udp_descriptor* udesc, int err) ErlDrvTermData am_err = error_atom(err); int i = 0; - DEBUGF(("packet_error_message(%ld): %d\r\n", - (long)desc->port, err)); + DEBUGF(("packet_error_message(%p): %d\r\n", + desc->port, err)); # ifdef HAVE_SCTP if (IS_SCTP(desc) ) @@ -4116,6 +4161,18 @@ static int inet_init() if (!sock_init()) goto error; +#if !defined(__WIN32__) && !defined(NO_SYSCONF) + iov_max = (int) sysconf(_SC_IOV_MAX); + if (iov_max < 0) { +#ifdef IOV_MAX + iov_max = IOV_MAX; +#else + iov_max = 16; /* min value required by POSIX */ +#endif + } + ASSERT(iov_max >= 16); +#endif + if (0 != erl_drv_tsd_key_create("inet_buffer_stack_key", &buffer_stack_key)) goto error; @@ -4626,10 +4683,10 @@ static void desc_close(inet_descriptor* desc) * be selecting on it. */ if (!INET_IGNORED(desc)) - driver_select(desc->port,(ErlDrvEvent)(long)desc->event, + driver_select(desc->port,(ErlDrvEvent)(SWord)desc->event, ERL_DRV_USE, 0); else - inet_stop_select((ErlDrvEvent)(long)desc->event,NULL); + inet_stop_select((ErlDrvEvent)(SWord)desc->event,NULL); desc->event = INVALID_EVENT; /* closed by stop_select callback */ desc->s = INVALID_SOCKET; desc->event_mask = 0; @@ -4778,7 +4835,7 @@ static ErlDrvSSizeT inet_ctl_fdopen(inet_descriptor* desc, int domain, int type, char** rbuf, ErlDrvSizeT rsize) { inet_address name; - unsigned int sz; + SOCKLEN_T sz; if (bound) { /* check that it is a socket and that the socket is bound */ @@ -5852,9 +5909,10 @@ static ErlDrvSSizeT inet_ctl_getifaddrs(inet_descriptor* desc_p, *buf_p++ = INET_REP_OK; /* Iterate over MIB_IPADDRTABLE or IP_ADAPTER_ADDRESSES */ - for (ia_p = NULL, ip_addrs_p ? ((void *)(i = 0)) : (ia_p = ip_adaddrs_p); + ia_p = NULL; + for (ip_addrs_p ? (void)(i = 0) : (void)(ia_p = ip_adaddrs_p); ip_addrs_p ? (i < ip_addrs_p->dwNumEntries) : (ia_p != NULL); - ip_addrs_p ? ((void *)(i++)) : (ia_p = ia_p->Next)) { + ip_addrs_p ? (void)(i++) : (void)(ia_p = ia_p->Next)) { MIB_IPADDRROW *ipaddrrow_p = NULL; DWORD flags = INET_IFF_MULTICAST; DWORD index = 0; @@ -6363,35 +6421,35 @@ static int inet_set_opts(inet_descriptor* desc, char* ptr, int len) switch(opt) { case INET_LOPT_HEADER: - DEBUGF(("inet_set_opts(%ld): s=%d, HEADER=%d\r\n", - (long)desc->port, desc->s,ival)); + DEBUGF(("inet_set_opts(%p): s=%d, HEADER=%d\r\n", + desc->port, desc->s,ival)); desc->hsz = ival; continue; case INET_LOPT_MODE: /* List or Binary: */ - DEBUGF(("inet_set_opts(%ld): s=%d, MODE=%d\r\n", - (long)desc->port, desc->s, ival)); + DEBUGF(("inet_set_opts(%p): s=%d, MODE=%d\r\n", + desc->port, desc->s, ival)); desc->mode = ival; continue; case INET_LOPT_DELIVER: - DEBUGF(("inet_set_opts(%ld): s=%d, DELIVER=%d\r\n", - (long)desc->port, desc->s, ival)); + DEBUGF(("inet_set_opts(%p): s=%d, DELIVER=%d\r\n", + desc->port, desc->s, ival)); desc->deliver = ival; continue; case INET_LOPT_BUFFER: - DEBUGF(("inet_set_opts(%ld): s=%d, BUFFER=%d\r\n", - (long)desc->port, desc->s, ival)); + DEBUGF(("inet_set_opts(%p): s=%d, BUFFER=%d\r\n", + desc->port, desc->s, ival)); if (ival < INET_MIN_BUFFER) ival = INET_MIN_BUFFER; desc->bufsz = ival; desc->flags |= INET_FLG_BUFFER_SET; continue; case INET_LOPT_ACTIVE: - DEBUGF(("inet_set_opts(%ld): s=%d, ACTIVE=%d\r\n", - (long)desc->port, desc->s, ival)); + DEBUGF(("inet_set_opts(%p): s=%d, ACTIVE=%d\r\n", + desc->port, desc->s, ival)); desc->active = ival; if (desc->active == INET_MULTI) { long ac = desc->active_count; @@ -6428,20 +6486,20 @@ static int inet_set_opts(inet_descriptor* desc, char* ptr, int len) continue; case INET_LOPT_PACKET: - DEBUGF(("inet_set_opts(%ld): s=%d, PACKET=%d\r\n", - (long)desc->port, desc->s, ival)); + DEBUGF(("inet_set_opts(%p): s=%d, PACKET=%d\r\n", + desc->port, desc->s, ival)); desc->htype = ival; continue; case INET_LOPT_PACKET_SIZE: - DEBUGF(("inet_set_opts(%ld): s=%d, PACKET_SIZE=%d\r\n", - (long)desc->port, desc->s, ival)); + DEBUGF(("inet_set_opts(%p): s=%d, PACKET_SIZE=%d\r\n", + desc->port, desc->s, ival)); desc->psize = (unsigned int)ival; continue; case INET_LOPT_EXITONCLOSE: - DEBUGF(("inet_set_opts(%ld): s=%d, EXITONCLOSE=%d\r\n", - (long)desc->port, desc->s, ival)); + DEBUGF(("inet_set_opts(%p): s=%d, EXITONCLOSE=%d\r\n", + desc->port, desc->s, ival)); desc->exitf = ival; continue; @@ -6545,8 +6603,8 @@ static int inet_set_opts(inet_descriptor* desc, char* ptr, int len) continue; case INET_LOPT_LINE_DELIM: - DEBUGF(("inet_set_opts(%ld): s=%d, LINE_DELIM=%d\r\n", - (long)desc->port, desc->s, ival)); + DEBUGF(("inet_set_opts(%p): s=%d, LINE_DELIM=%d\r\n", + desc->port, desc->s, ival)); desc->delimiter = (char)ival; continue; @@ -6555,33 +6613,33 @@ static int inet_set_opts(inet_descriptor* desc, char* ptr, int len) continue; /* Bjorn says */ #else type = SO_REUSEADDR; - DEBUGF(("inet_set_opts(%ld): s=%d, SO_REUSEADDR=%d\r\n", - (long)desc->port, desc->s,ival)); + DEBUGF(("inet_set_opts(%p): s=%d, SO_REUSEADDR=%d\r\n", + desc->port, desc->s,ival)); break; #endif case INET_OPT_KEEPALIVE: type = SO_KEEPALIVE; - DEBUGF(("inet_set_opts(%ld): s=%d, SO_KEEPALIVE=%d\r\n", - (long)desc->port, desc->s, ival)); + DEBUGF(("inet_set_opts(%p): s=%d, SO_KEEPALIVE=%d\r\n", + desc->port, desc->s, ival)); break; case INET_OPT_DONTROUTE: type = SO_DONTROUTE; - DEBUGF(("inet_set_opts(%ld): s=%d, SO_DONTROUTE=%d\r\n", - (long)desc->port, desc->s, ival)); + DEBUGF(("inet_set_opts(%p): s=%d, SO_DONTROUTE=%d\r\n", + desc->port, desc->s, ival)); break; case INET_OPT_BROADCAST: type = SO_BROADCAST; - DEBUGF(("inet_set_opts(%ld): s=%d, SO_BROADCAST=%d\r\n", - (long)desc->port, desc->s,ival)); + DEBUGF(("inet_set_opts(%p): s=%d, SO_BROADCAST=%d\r\n", + desc->port, desc->s, ival)); break; case INET_OPT_OOBINLINE: type = SO_OOBINLINE; - DEBUGF(("inet_set_opts(%ld): s=%d, SO_OOBINLINE=%d\r\n", - (long)desc->port, desc->s, ival)); + DEBUGF(("inet_set_opts(%p): s=%d, SO_OOBINLINE=%d\r\n", + desc->port, desc->s, ival)); break; case INET_OPT_SNDBUF: type = SO_SNDBUF; - DEBUGF(("inet_set_opts(%ld): s=%d, SO_SNDBUF=%d\r\n", - (long)desc->port, desc->s, ival)); + DEBUGF(("inet_set_opts(%p): s=%d, SO_SNDBUF=%d\r\n", + desc->port, desc->s, ival)); break; case INET_OPT_RCVBUF: type = SO_RCVBUF; - DEBUGF(("inet_set_opts(%ld): s=%d, SO_RCVBUF=%d\r\n", - (long)desc->port, desc->s, ival)); + DEBUGF(("inet_set_opts(%p): s=%d, SO_RCVBUF=%d\r\n", + desc->port, desc->s, ival)); if (!(desc->flags & INET_FLG_BUFFER_SET)) { /* make sure we have desc->bufsz >= SO_RCVBUF */ if (ival > (1 << 16) && desc->stype == SOCK_DGRAM && !IS_SCTP(desc)) @@ -6602,8 +6660,9 @@ static int inet_set_opts(inet_descriptor* desc, char* ptr, int len) len -= 4; arg_ptr = (char*) &li_val; arg_sz = sizeof(li_val); - DEBUGF(("inet_set_opts(%ld): s=%d, SO_LINGER=%d,%d", - (long)desc->port, desc->s, li_val.l_onoff,li_val.l_linger)); + DEBUGF(("inet_set_opts(%p): s=%d, SO_LINGER=%d,%d", + desc->port, desc->s, + li_val.l_onoff,li_val.l_linger)); if (desc->sprotocol == IPPROTO_TCP) { tcp_descriptor* tdesc = (tcp_descriptor*) desc; if (li_val.l_onoff && li_val.l_linger == 0) @@ -6617,8 +6676,8 @@ static int inet_set_opts(inet_descriptor* desc, char* ptr, int len) #ifdef SO_PRIORITY type = SO_PRIORITY; propagate = 1; /* We do want to know if this fails */ - DEBUGF(("inet_set_opts(%ld): s=%d, SO_PRIORITY=%d\r\n", - (long)desc->port, desc->s, ival)); + DEBUGF(("inet_set_opts(%p): s=%d, SO_PRIORITY=%d\r\n", + desc->port, desc->s, ival)); break; #else /* inet_fill_opts always returns a value for this option, @@ -6630,8 +6689,8 @@ static int inet_set_opts(inet_descriptor* desc, char* ptr, int len) proto = IPPROTO_IP; type = IP_TOS; propagate = 1; - DEBUGF(("inet_set_opts(%ld): s=%d, IP_TOS=%d\r\n", - (long)desc->port, desc->s, ival)); + DEBUGF(("inet_set_opts(%p): s=%d, IP_TOS=%d\r\n", + desc->port, desc->s, ival)); break; #else /* inet_fill_opts always returns a value for this option, @@ -6643,8 +6702,8 @@ static int inet_set_opts(inet_descriptor* desc, char* ptr, int len) proto = IPPROTO_IPV6; type = IPV6_TCLASS; propagate = 1; - DEBUGF(("inet_set_opts(%ld): s=%d, IPV6_TCLASS=%d\r\n", - (long)desc->port, desc->s, ival)); + DEBUGF(("inet_set_opts(%p): s=%d, IPV6_TCLASS=%d\r\n", + desc->port, desc->s, ival)); break; #endif #if defined(IP_TTL) && defined(IPPROTO_IP) @@ -6652,8 +6711,8 @@ static int inet_set_opts(inet_descriptor* desc, char* ptr, int len) proto = IPPROTO_IP; type = IP_TTL; propagate = 1; - DEBUGF(("inet_set_opts(%ld): s=%d, IP_TTL=%d\r\n", - (long)desc->port, desc->s, ival)); + DEBUGF(("inet_set_opts(%p): s=%d, IP_TTL=%d\r\n", + desc->port, desc->s, ival)); break; #endif #if defined(IP_RECVTOS) && defined(IPPROTO_IP) @@ -6665,8 +6724,8 @@ static int inet_set_opts(inet_descriptor* desc, char* ptr, int len) ival ? (desc->recv_cmsgflags | INET_CMSG_RECVTOS) : (desc->recv_cmsgflags & ~INET_CMSG_RECVTOS); - DEBUGF(("inet_set_opts(%ld): s=%d, IP_RECVTOS=%d\r\n", - (long)desc->port, desc->s, ival)); + DEBUGF(("inet_set_opts(%p): s=%d, IP_RECVTOS=%d\r\n", + desc->port, desc->s, ival)); break; #endif #if defined(IPV6_RECVTCLASS) && defined(IPPROTO_IPV6) @@ -6678,8 +6737,8 @@ static int inet_set_opts(inet_descriptor* desc, char* ptr, int len) ival ? (desc->recv_cmsgflags | INET_CMSG_RECVTCLASS) : (desc->recv_cmsgflags & ~INET_CMSG_RECVTCLASS); - DEBUGF(("inet_set_opts(%ld): s=%d, IPV6_RECVTCLASS=%d\r\n", - (long)desc->port, desc->s, ival)); + DEBUGF(("inet_set_opts(%p): s=%d, IPV6_RECVTCLASS=%d\r\n", + desc->port, desc->s, ival)); break; #endif #if defined(IP_RECVTTL) && defined(IPPROTO_IP) @@ -6691,24 +6750,24 @@ static int inet_set_opts(inet_descriptor* desc, char* ptr, int len) ival ? (desc->recv_cmsgflags | INET_CMSG_RECVTTL) : (desc->recv_cmsgflags & ~INET_CMSG_RECVTTL); - DEBUGF(("inet_set_opts(%ld): s=%d, IP_RECVTTL=%d\r\n", - (long)desc->port, desc->s, ival)); + DEBUGF(("inet_set_opts(%p): s=%d, IP_RECVTTL=%d\r\n", + desc->port, desc->s, ival)); break; #endif case TCP_OPT_NODELAY: proto = IPPROTO_TCP; type = TCP_NODELAY; - DEBUGF(("inet_set_opts(%ld): s=%d, TCP_NODELAY=%d\r\n", - (long)desc->port, desc->s, ival)); + DEBUGF(("inet_set_opts(%p): s=%d, TCP_NODELAY=%d\r\n", + desc->port, desc->s, ival)); break; case TCP_OPT_NOPUSH: #if defined(INET_TCP_NOPUSH) proto = IPPROTO_TCP; type = INET_TCP_NOPUSH; - DEBUGF(("inet_set_opts(%ld): s=%d, t=%d TCP_NOPUSH=%d\r\n", - (long)desc->port, desc->s, type, ival)); + DEBUGF(("inet_set_opts(%p): s=%d, t=%d TCP_NOPUSH=%d\r\n", + desc->port, desc->s, type, ival)); break; #else /* inet_fill_opts always returns a value for this option, @@ -6721,37 +6780,38 @@ static int inet_set_opts(inet_descriptor* desc, char* ptr, int len) case UDP_OPT_MULTICAST_TTL: proto = IPPROTO_IP; type = IP_MULTICAST_TTL; - DEBUGF(("inet_set_opts(%ld): s=%d, IP_MULTICAST_TTL=%d\r\n", - (long)desc->port,desc->s,ival)); + DEBUGF(("inet_set_opts(%p): s=%d, IP_MULTICAST_TTL=%d\r\n", + desc->port, desc->s,ival)); break; case UDP_OPT_MULTICAST_LOOP: proto = IPPROTO_IP; type = IP_MULTICAST_LOOP; - DEBUGF(("inet_set_opts(%ld): s=%d, IP_MULTICAST_LOOP=%d\r\n", - (long)desc->port,desc->s,ival)); + DEBUGF(("inet_set_opts(%p): s=%d, IP_MULTICAST_LOOP=%d\r\n", + desc->port, desc->s,ival)); break; case UDP_OPT_MULTICAST_IF: proto = IPPROTO_IP; type = IP_MULTICAST_IF; - DEBUGF(("inet_set_opts(%ld): s=%d, IP_MULTICAST_IF=%x\r\n", - (long)desc->port, desc->s, ival)); + DEBUGF(("inet_set_opts(%p): s=%d, IP_MULTICAST_IF=%x\r\n", + desc->port, desc->s, ival)); ival = sock_htonl(ival); break; case UDP_OPT_ADD_MEMBERSHIP: proto = IPPROTO_IP; type = IP_ADD_MEMBERSHIP; - DEBUGF(("inet_set_opts(%ld): s=%d, IP_ADD_MEMBERSHIP=%d\r\n", - (long)desc->port, desc->s,ival)); + DEBUGF(("inet_set_opts(%p): s=%d, IP_ADD_MEMBERSHIP=%d\r\n", + desc->port, desc->s,ival)); goto L_set_mreq; case UDP_OPT_DROP_MEMBERSHIP: proto = IPPROTO_IP; type = IP_DROP_MEMBERSHIP; - DEBUGF(("inet_set_opts(%ld): s=%d, IP_DROP_MEMBERSHIP=%x\r\n", - (long)desc->port, desc->s, ival)); + DEBUGF(("inet_set_opts(%p): s=%d, " + "IP_DROP_MEMBERSHIP=%x\r\n", + desc->port, desc->s, ival)); L_set_mreq: mreq_val.imr_multiaddr.s_addr = sock_htonl(ival); ival = get_int32(ptr); @@ -6769,8 +6829,8 @@ static int inet_set_opts(inet_descriptor* desc, char* ptr, int len) proto = IPPROTO_IPV6; type = IPV6_V6ONLY; propagate = 1; - DEBUGF(("inet_set_opts(%ld): s=%d, IPV6_V6ONLY=%d\r\n", - (long)desc->port, desc->s, ival)); + DEBUGF(("inet_set_opts(%p): s=%d, IPV6_V6ONLY=%d\r\n", + desc->port, desc->s, ival)); break; #elif defined(__WIN32__) && defined(HAVE_IN6) && defined(AF_INET6) /* Fake a'la OpenBSD; set to 'true' is fine but 'false' invalid. */ @@ -6817,8 +6877,8 @@ static int inet_set_opts(inet_descriptor* desc, char* ptr, int len) arg_sz = sizeof(ifname); propagate = 1; /* We do want to know if this fails */ - DEBUGF(("inet_set_opts(%ld): s=%d, SO_BINDTODEVICE=%s\r\n", - (long)desc->port, desc->s, ifname)); + DEBUGF(("inet_set_opts(%p): s=%d, SO_BINDTODEVICE=%s\r\n", + desc->port, desc->s, ifname)); break; #endif @@ -6835,32 +6895,40 @@ static int inet_set_opts(inet_descriptor* desc, char* ptr, int len) if (propagate && res != 0) { return -1; } - DEBUGF(("inet_set_opts(%ld): s=%d returned %d\r\n", - (long)desc->port, desc->s, res)); + DEBUGF(("inet_set_opts(%p): s=%d returned %d\r\n", + desc->port, desc->s, res)); } if ( ((desc->stype == SOCK_STREAM) && IS_CONNECTED(desc)) || ((desc->stype == SOCK_DGRAM) && IS_OPEN(desc))) { + int trigger_recv; + + /* XXX: UDP sockets could also trigger immediate read here NIY */ + trigger_recv = + (desc->stype==SOCK_STREAM) && + !old_active && + (desc->active == INET_ONCE || desc->active == INET_MULTI) && + (desc->htype == old_htype); + + if (trigger_recv) { + return 2; + } if (desc->active != old_active) { /* Need to cancel the read_packet timer if we go from active to passive. */ if (desc->active == INET_PASSIVE && desc->stype == SOCK_DGRAM) driver_cancel_timer(desc->port); - sock_select(desc, (FD_READ|FD_CLOSE), (desc->active>0)); + + sock_select(desc, (FD_READ|FD_CLOSE), (desc->active>0)); } /* XXX: UDP sockets could also trigger immediate read here NIY */ if ((desc->stype==SOCK_STREAM) && desc->active) { if (!old_active || (desc->htype != old_htype)) { /* passive => active change OR header type change in active mode */ - /* Return > 1 if only active changed to INET_ONCE -> direct read if - header type is unchanged. */ - /* XXX fprintf(stderr,"desc->htype == %d, old_htype == %d, - desc->active == %d, old_active == %d\r\n",(int)desc->htype, - (int) old_htype, (int) desc->active, (int) old_active );*/ - return 1+(desc->htype == old_htype && - (desc->active == INET_ONCE || desc->active == INET_MULTI)); + return 1; } + return 0; } } @@ -6952,9 +7020,9 @@ static int sctp_set_opts(inet_descriptor* desc, char* ptr, int len) struct sctp_paddrparams pap; struct sctp_sndrcvinfo sri; struct sctp_event_subscribe es; -# ifdef SCTP_DELAYED_ACK_TIME +#if defined(HAVE_DECL_SCTP_DELAYED_ACK_TIME) && defined(SCTP_ASSOC_VALUE_ASSOC_ID) struct sctp_assoc_value av; /* Not in SOLARIS10 */ -# endif +#endif # ifdef SO_BINDTODEVICE char ifname[IFNAMSIZ]; # endif @@ -7473,8 +7541,9 @@ static int sctp_set_opts(inet_descriptor* desc, char* ptr, int len) arg_sz = sizeof ( arg.es); break; } - /* The following is not available on Solaris 10: */ -# ifdef SCTP_DELAYED_ACK_TIME + /* The following is not available on + * Solaris 10 or NetBSD or ... */ +#if defined(HAVE_DECL_SCTP_DELAYED_ACK_TIME) && defined(SCTP_ASSOC_VALUE_ASSOC_ID) case SCTP_OPT_DELAYED_ACK_TIME: { CHKLEN(curr, ASSOC_ID_LEN + 4); @@ -7487,7 +7556,7 @@ static int sctp_set_opts(inet_descriptor* desc, char* ptr, int len) arg_sz = sizeof ( arg.av); break; } -# endif +#endif default: /* XXX: No more supported SCTP options. In particular, authentica- tion options (SCTP_AUTH_CHUNK, SCTP_AUTH_KEY, SCTP_PEER_AUTH_ @@ -8100,7 +8169,9 @@ static int load_paddrinfo (ErlDrvTermData * spec, int i, { i = LOAD_ATOM (spec, i, am_sctp_paddrinfo); i = LOAD_ASSOC_ID (spec, i, pai->spinfo_assoc_id); + PUSH_SUPPRESS_ADDRESS_OF_PACKED_MEMBER(); i = load_inet_get_address(spec, i, desc, &pai->spinfo_address); + POP_SUPPRESS_ADDRESS_OF_PACKED_MEMBER(); switch(pai->spinfo_state) { case SCTP_ACTIVE: @@ -8620,7 +8691,9 @@ static ErlDrvSSizeT sctp_fill_opts(inet_descriptor* desc, ASSERT(0); } i = LOAD_ASSOC_ID (spec, i, sp.sspp_assoc_id); + PUSH_SUPPRESS_ADDRESS_OF_PACKED_MEMBER(); i = load_inet_get_address(spec, i, desc, &sp.sspp_addr); + POP_SUPPRESS_ADDRESS_OF_PACKED_MEMBER(); i = LOAD_TUPLE (spec, i, 3); i = LOAD_TUPLE (spec, i, 2); break; @@ -8680,7 +8753,9 @@ static ErlDrvSSizeT sctp_fill_opts(inet_descriptor* desc, i = LOAD_ATOM (spec, i, am_sctp_peer_addr_params); i = LOAD_ATOM (spec, i, am_sctp_paddrparams); i = LOAD_ASSOC_ID (spec, i, ap.spp_assoc_id); + PUSH_SUPPRESS_ADDRESS_OF_PACKED_MEMBER(); i = load_inet_get_address(spec, i, desc, &ap.spp_address); + POP_SUPPRESS_ADDRESS_OF_PACKED_MEMBER(); i = LOAD_INT (spec, i, ap.spp_hbinterval); i = LOAD_INT (spec, i, ap.spp_pathmaxrxt); @@ -8788,8 +8863,9 @@ static ErlDrvSSizeT sctp_fill_opts(inet_descriptor* desc, i = LOAD_TUPLE (spec, i, 2); break; } - /* The following option is not available in Solaris 10: */ -# if HAVE_DECL_SCTP_DELAYED_ACK_TIME + /* The following option is not available on: + * Solaris 10 or NetBSD or ... */ +#if defined(HAVE_DECL_SCTP_DELAYED_ACK_TIME) && defined(SCTP_ASSOC_VALUE_ASSOC_ID) case SCTP_OPT_DELAYED_ACK_TIME: { struct sctp_assoc_value av; @@ -9093,8 +9169,8 @@ static void inet_emergency_close(ErlDrvData data) /* valid for any (UDP, TCP or SCTP) descriptor */ tcp_descriptor* tcp_desc = (tcp_descriptor*)data; inet_descriptor* desc = INETP(tcp_desc); - DEBUGF(("inet_emergency_close(%ld) {s=%d\r\n", - (long)desc->port, desc->s)); + DEBUGF(("inet_emergency_close(%p) {s=%d\r\n", + desc->port, desc->s)); if (desc->s != INVALID_SOCKET) { sock_close(desc->s); } @@ -9215,7 +9291,7 @@ static ErlDrvSSizeT inet_ctl(inet_descriptor* desc, int cmd, char* buf, default: dstlen += 5; break; } } - DEBUGF(("inet_ctl(%ld): GETSTAT\r\n", (long) desc->port)); + DEBUGF(("inet_ctl(%p): GETSTAT\r\n", (long) desc->port)); if (dstlen > INET_MAX_OPT_BUFFER) /* sanity check */ return 0; if (dstlen > rsize) { @@ -9231,7 +9307,8 @@ static ErlDrvSSizeT inet_ctl(inet_descriptor* desc, int cmd, char* buf, case INET_REQ_SUBSCRIBE: { char* dst; int dstlen = 1 /* Reply code */ + len*5; - DEBUGF(("inet_ctl(%ld): INET_REQ_SUBSCRIBE\r\n", (long) desc->port)); + DEBUGF(("inet_ctl(%p): INET_REQ_SUBSCRIBE\r\n", + desc->port)); if (dstlen > INET_MAX_OPT_BUFFER) /* sanity check */ return 0; if (dstlen > rsize) { @@ -9246,7 +9323,7 @@ static ErlDrvSSizeT inet_ctl(inet_descriptor* desc, int cmd, char* buf, case INET_REQ_GETOPTS: { /* get options */ ErlDrvSSizeT replen; - DEBUGF(("inet_ctl(%ld): GETOPTS\r\n", (long)desc->port)); + DEBUGF(("inet_ctl(%p): GETOPTS\r\n", desc->port)); #ifdef HAVE_SCTP if (IS_SCTP(desc)) { @@ -9261,36 +9338,36 @@ static ErlDrvSSizeT inet_ctl(inet_descriptor* desc, int cmd, char* buf, } case INET_REQ_GETIFLIST: { - DEBUGF(("inet_ctl(%ld): GETIFLIST\r\n", (long)desc->port)); + DEBUGF(("inet_ctl(%p): GETIFLIST\r\n", desc->port)); if (!IS_OPEN(desc)) return ctl_xerror(EXBADPORT, rbuf, rsize); return inet_ctl_getiflist(desc, rbuf, rsize); } case INET_REQ_GETIFADDRS: { - DEBUGF(("inet_ctl(%ld): GETIFADDRS\r\n", (long)desc->port)); + DEBUGF(("inet_ctl(%p): GETIFADDRS\r\n", desc->port)); if (!IS_OPEN(desc)) return ctl_xerror(EXBADPORT, rbuf, rsize); return inet_ctl_getifaddrs(desc, rbuf, rsize); } case INET_REQ_IFGET: { - DEBUGF(("inet_ctl(%ld): IFGET\r\n", (long)desc->port)); + DEBUGF(("inet_ctl(%p): IFGET\r\n", desc->port)); if (!IS_OPEN(desc)) return ctl_xerror(EXBADPORT, rbuf, rsize); return inet_ctl_ifget(desc, buf, len, rbuf, rsize); } case INET_REQ_IFSET: { - DEBUGF(("inet_ctl(%ld): IFSET\r\n", (long)desc->port)); + DEBUGF(("inet_ctl(%p): IFSET\r\n", desc->port)); if (!IS_OPEN(desc)) return ctl_xerror(EXBADPORT, rbuf, rsize); return inet_ctl_ifset(desc, buf, len, rbuf, rsize); } case INET_REQ_SETOPTS: { /* set options */ - DEBUGF(("inet_ctl(%ld): SETOPTS\r\n", (long)desc->port)); - /* XXX fprintf(stderr,"inet_ctl(%ld): SETOPTS (len = %d)\r\n", (long)desc->port,(int) len); */ + DEBUGF(("inet_ctl(%p): SETOPTS\r\n", desc->port)); + /* XXX fprintf(stderr,"inet_ctl(%p): SETOPTS (len = %d)\r\n", desc->port,(int) len); */ switch(inet_set_opts(desc, buf, len)) { case -1: return ctl_error(EINVAL, rbuf, rsize); @@ -9309,7 +9386,9 @@ static ErlDrvSSizeT inet_ctl(inet_descriptor* desc, int cmd, char* buf, * Same as above, but active changed to once w/o header type * change, so try a read instead of just deliver. */ - tcp_recv((tcp_descriptor *) desc, 0); + if ((tcp_recv((tcp_descriptor *) desc, 0) >= 0) && desc->active) { + sock_select(desc, (FD_READ|FD_CLOSE), 1); + } return ctl_reply(INET_REP_OK, NULL, 0, rbuf, rsize); } } @@ -9317,7 +9396,7 @@ static ErlDrvSSizeT inet_ctl(inet_descriptor* desc, int cmd, char* buf, case INET_REQ_GETSTATUS: { char tbuf[4]; - DEBUGF(("inet_ctl(%ld): GETSTATUS\r\n", (long)desc->port)); + DEBUGF(("inet_ctl(%p): GETSTATUS\r\n", desc->port)); put_int32(desc->state, tbuf); return ctl_reply(INET_REP_OK, tbuf, 4, rbuf, rsize); } @@ -9325,7 +9404,7 @@ static ErlDrvSSizeT inet_ctl(inet_descriptor* desc, int cmd, char* buf, case INET_REQ_GETTYPE: { char tbuf[8]; - DEBUGF(("inet_ctl(%ld): GETTYPE\r\n", (long)desc->port)); + DEBUGF(("inet_ctl(%p): GETTYPE\r\n", desc->port)); if (desc->sfamily == AF_INET) { put_int32(INET_AF_INET, &tbuf[0]); } @@ -9362,7 +9441,7 @@ static ErlDrvSSizeT inet_ctl(inet_descriptor* desc, int cmd, char* buf, case INET_REQ_GETFD: { char tbuf[4]; - DEBUGF(("inet_ctl(%ld): GETFD\r\n", (long)desc->port)); + DEBUGF(("inet_ctl(%p): GETFD\r\n", desc->port)); if (!IS_OPEN(desc)) return ctl_error(EINVAL, rbuf, rsize); put_int32((long)desc->s, tbuf); @@ -9372,7 +9451,8 @@ static ErlDrvSSizeT inet_ctl(inet_descriptor* desc, int cmd, char* buf, case INET_REQ_GETHOSTNAME: { /* get host name */ char tbuf[INET_MAXHOSTNAMELEN + 1]; - DEBUGF(("inet_ctl(%ld): GETHOSTNAME\r\n", (long)desc->port)); + DEBUGF(("inet_ctl(%p): GETHOSTNAME\r\n", + desc->port)); if (len != 0) return ctl_error(EINVAL, rbuf, rsize); @@ -9383,7 +9463,8 @@ static ErlDrvSSizeT inet_ctl(inet_descriptor* desc, int cmd, char* buf, } case INET_REQ_GETPADDRS: { - DEBUGF(("inet_ctl(%ld): INET_GETPADDRS\r\n", (long)desc->port)); + DEBUGF(("inet_ctl(%p): INET_GETPADDRS\r\n", + desc->port)); if (len != 4) return ctl_error(EINVAL, rbuf, rsize); @@ -9420,7 +9501,7 @@ static ErlDrvSSizeT inet_ctl(inet_descriptor* desc, int cmd, char* buf, inet_address* ptr; unsigned int sz; - DEBUGF(("inet_ctl(%ld): PEER\r\n", (long)desc->port)); + DEBUGF(("inet_ctl(%p): PEER\r\n", desc->port)); if (!(desc->state & INET_F_ACTIVE)) return ctl_error(ENOTCONN, rbuf, rsize); @@ -9454,13 +9535,14 @@ static ErlDrvSSizeT inet_ctl(inet_descriptor* desc, int cmd, char* buf, return ctl_xerror(xerror, rbuf, rsize); else { desc->peer_ptr = &desc->peer_addr; - desc->peer_addr_len = (SOCKLEN_T) len; + desc->peer_addr_len = (unsigned int) len; return ctl_reply(INET_REP_OK, NULL, 0, rbuf, rsize); } } case INET_REQ_GETLADDRS: { - DEBUGF(("inet_ctl(%ld): INET_GETLADDRS\r\n", (long)desc->port)); + DEBUGF(("inet_ctl(%p): INET_GETLADDRS\r\n", + desc->port)); if (len != 4) return ctl_error(EINVAL, rbuf, rsize); @@ -9498,7 +9580,7 @@ static ErlDrvSSizeT inet_ctl(inet_descriptor* desc, int cmd, char* buf, inet_address* ptr; unsigned int sz; - DEBUGF(("inet_ctl(%ld): NAME\r\n", (long)desc->port)); + DEBUGF(("inet_ctl(%p): NAME\r\n", desc->port)); if ((ptr = desc->name_ptr) != NULL) { sz = desc->name_addr_len; @@ -9529,7 +9611,7 @@ static ErlDrvSSizeT inet_ctl(inet_descriptor* desc, int cmd, char* buf, return ctl_xerror(xerror, rbuf, rsize); else { desc->name_ptr = &desc->name_addr; - desc->name_addr_len = (SOCKLEN_T) len; + desc->name_addr_len = (unsigned int) len; return ctl_reply(INET_REP_OK, NULL, 0, rbuf, rsize); } } @@ -9539,7 +9621,7 @@ static ErlDrvSSizeT inet_ctl(inet_descriptor* desc, int cmd, char* buf, inet_address local; int port; - DEBUGF(("inet_ctl(%ld): BIND\r\n", (long)desc->port)); + DEBUGF(("inet_ctl(%p): BIND\r\n", desc->port)); if (len < 2) return ctl_error(EINVAL, rbuf, rsize); @@ -9568,8 +9650,8 @@ static ErlDrvSSizeT inet_ctl(inet_descriptor* desc, int cmd, char* buf, } case INET_REQ_IGNOREFD: { - DEBUGF(("inet_ctl(%ld): IGNOREFD, IGNORED = %d\r\n", - (long)desc->port,(int)*buf)); + DEBUGF(("inet_ctl(%p): IGNOREFD, IGNORED = %d\r\n", + desc->port,(int)*buf)); /* * FD can only be ignored for connected TCP connections for now, @@ -9743,8 +9825,9 @@ static int tcp_expand_buffer(tcp_descriptor* desc, int len) return 0; } - DEBUGF(("tcp_expand_buffer(%ld): s=%d, from %ld to %d\r\n", - (long)desc->inet.port, desc->inet.s, desc->i_buf->orig_size, ulen)); + DEBUGF(("tcp_expand_buffer(%p): s=%d, from %ld to %d\r\n", + desc->inet.port, desc->inet.s, + desc->i_buf->orig_size, ulen)); offs1 = desc->i_ptr_start - desc->i_buf->orig_bytes; offs2 = desc->i_ptr - desc->i_ptr_start; @@ -9844,7 +9927,7 @@ static int tcp_inet_init(void) static ErlDrvData prep_tcp_inet_start(ErlDrvPort port, char* args) { tcp_descriptor* desc; - DEBUGF(("tcp_inet_start(%ld) {\r\n", (long)port)); + DEBUGF(("tcp_inet_start(%p) {\r\n", port)); desc = (tcp_descriptor*) inet_start(port, sizeof(tcp_descriptor), IPPROTO_TCP); @@ -9865,7 +9948,7 @@ static ErlDrvData prep_tcp_inet_start(ErlDrvPort port, char* args) desc->mtd = NULL; desc->mtd_cache = NULL; desc->multi_first = desc->multi_last = NULL; - DEBUGF(("tcp_inet_start(%ld) }\r\n", (long)port)); + DEBUGF(("tcp_inet_start(%p) }\r\n", port)); return (ErlDrvData) desc; } @@ -9918,7 +10001,7 @@ static tcp_descriptor* tcp_inet_copy(tcp_descriptor* desc,SOCKET s, /* The new port will be linked and connected to the original caller */ port = driver_create_port(port, owner, "tcp_inet", (ErlDrvData) copy_desc); - if ((long)port == -1) { + if ((SWord)port == -1) { *err = INET_ERRNO_SYSTEM_LIMIT; FREE(copy_desc); return NULL; @@ -9981,13 +10064,22 @@ static void tcp_close_check(tcp_descriptor* desc) static void tcp_inet_stop(ErlDrvData e) { tcp_descriptor* desc = (tcp_descriptor*)e; - DEBUGF(("tcp_inet_stop(%ld) {s=%d\r\n", - (long)desc->inet.port, desc->inet.s)); + DEBUGF(("tcp_inet_stop(%p) {s=%d\r\n", + desc->inet.port, desc->inet.s)); tcp_close_check(desc); tcp_clear_input(desc); - DEBUGF(("tcp_inet_stop(%ld) }\r\n", (long)desc->inet.port)); +#ifdef HAVE_SENDFILE + if(desc->tcp_add_flags & TCP_ADDF_SENDFILE) { + desc->tcp_add_flags &= ~TCP_ADDF_SENDFILE; + close(desc->sendfile.dup_file_fd); + DEBUGF(("tcp_inet_stop(%p): SENDFILE dup closed %d\r\n", + desc->inet.port, desc->sendfile.dup_file_fd)); + } +#endif + + DEBUGF(("tcp_inet_stop(%p) }\r\n", desc->inet.port)); inet_stop(INETP(desc)); } @@ -10002,12 +10094,6 @@ static void tcp_inet_stop(ErlDrvData e) * will be freed through tcp_inet_stop later on. */ static void tcp_desc_close(tcp_descriptor* desc) { -#ifdef HAVE_SENDFILE - if(desc->tcp_add_flags & TCP_ADDF_SENDFILE) { - desc->tcp_add_flags &= ~TCP_ADDF_SENDFILE; - close(desc->sendfile.dup_file_fd); - } -#endif tcp_clear_input(desc); tcp_clear_output(desc); @@ -10035,7 +10121,8 @@ static ErlDrvSSizeT tcp_inet_ctl(ErlDrvData e, unsigned int cmd, switch(cmd) { case INET_REQ_OPEN: { /* open socket and return internal index */ int domain; - DEBUGF(("tcp_inet_ctl(%ld): OPEN\r\n", (long)desc->inet.port)); + DEBUGF(("tcp_inet_ctl(%p): OPEN\r\n", + desc->inet.port)); if (len != 2) return ctl_error(EINVAL, rbuf, rsize); switch(buf[0]) { case INET_AF_INET: @@ -10062,7 +10149,8 @@ static ErlDrvSSizeT tcp_inet_ctl(ErlDrvData e, unsigned int cmd, case INET_REQ_FDOPEN: { /* pass in an open (and optionally bound) socket */ int domain; int bound; - DEBUGF(("tcp_inet_ctl(%ld): FDOPEN\r\n", (long)desc->inet.port)); + DEBUGF(("tcp_inet_ctl(%p): FDOPEN\r\n", + desc->inet.port)); if (len != 6 && len != 10) return ctl_error(EINVAL, rbuf, rsize); switch(buf[0]) { case INET_AF_INET: @@ -10095,7 +10183,8 @@ static ErlDrvSSizeT tcp_inet_ctl(ErlDrvData e, unsigned int cmd, case INET_REQ_LISTEN: { /* argument backlog */ int backlog; - DEBUGF(("tcp_inet_ctl(%ld): LISTEN\r\n", (long)desc->inet.port)); + DEBUGF(("tcp_inet_ctl(%p): LISTEN\r\n", + desc->inet.port)); if (desc->inet.state == INET_STATE_CLOSED) return ctl_xerror(EXBADPORT, rbuf, rsize); if (!IS_OPEN(INETP(desc))) @@ -10115,7 +10204,8 @@ static ErlDrvSSizeT tcp_inet_ctl(ErlDrvData e, unsigned int cmd, char tbuf[2], *xerror; unsigned timeout; - DEBUGF(("tcp_inet_ctl(%ld): CONNECT\r\n", (long)desc->inet.port)); + DEBUGF(("tcp_inet_ctl(%p): CONNECT\r\n", + desc->inet.port)); /* INPUT: Timeout(4), Port(2), Address(N) */ if (!IS_OPEN(INETP(desc))) @@ -10164,7 +10254,8 @@ static ErlDrvSSizeT tcp_inet_ctl(ErlDrvData e, unsigned int cmd, unsigned int n; SOCKET s; - DEBUGF(("tcp_inet_ctl(%ld): ACCEPT\r\n", (long)desc->inet.port)); + DEBUGF(("tcp_inet_ctl(%p): ACCEPT\r\n", + desc->inet.port)); /* INPUT: Timeout(4) */ if ((desc->inet.state != INET_STATE_LISTENING && desc->inet.state != INET_STATE_ACCEPTING && @@ -10267,7 +10358,8 @@ static ErlDrvSSizeT tcp_inet_ctl(ErlDrvData e, unsigned int cmd, } } case INET_REQ_CLOSE: - DEBUGF(("tcp_inet_ctl(%ld): CLOSE\r\n", (long)desc->inet.port)); + DEBUGF(("tcp_inet_ctl(%p): CLOSE\r\n", + desc->inet.port)); tcp_close_check(desc); tcp_desc_close(desc); return ctl_reply(INET_REP_OK, NULL, 0, rbuf, rsize); @@ -10278,8 +10370,8 @@ static ErlDrvSSizeT tcp_inet_ctl(ErlDrvData e, unsigned int cmd, char tbuf[2]; int n; - DEBUGF(("tcp_inet_ctl(%ld): RECV (s=%d)\r\n", - (long)desc->inet.port, desc->inet.s)); + DEBUGF(("tcp_inet_ctl(%p): RECV (s=%d)\r\n", + desc->inet.port, desc->inet.s)); /* INPUT: Timeout(4), Length(4) */ if (!IS_CONNECTED(INETP(desc))) { if (desc->tcp_add_flags & TCP_ADDF_DELAYED_CLOSE_RECV) { @@ -10298,8 +10390,8 @@ static ErlDrvSSizeT tcp_inet_ctl(ErlDrvData e, unsigned int cmd, timeout = get_int32(buf); buf += 4; n = get_int32(buf); - DEBUGF(("tcp_inet_ctl(%ld) timeout = %d, n = %d\r\n", - (long)desc->inet.port,timeout,n)); + DEBUGF(("tcp_inet_ctl(%p) timeout = %d, n = %d\r\n", + desc->inet.port,timeout,n)); if ((desc->inet.htype != TCP_PB_RAW) && (n != 0)) return ctl_error(EINVAL, rbuf, rsize); if (n > TCP_MAX_PACKET_SIZE) @@ -10324,7 +10416,8 @@ static ErlDrvSSizeT tcp_inet_ctl(ErlDrvData e, unsigned int cmd, } case TCP_REQ_UNRECV: { - DEBUGF(("tcp_inet_ctl(%ld): UNRECV\r\n", (long)desc->inet.port)); + DEBUGF(("tcp_inet_ctl(%p): UNRECV\r\n", + desc->inet.port)); if (!IS_CONNECTED(INETP(desc))) return ctl_error(ENOTCONN, rbuf, rsize); tcp_push_buffer(desc, buf, len); @@ -10334,7 +10427,8 @@ static ErlDrvSSizeT tcp_inet_ctl(ErlDrvData e, unsigned int cmd, } case TCP_REQ_SHUTDOWN: { int how; - DEBUGF(("tcp_inet_ctl(%ld): FDOPEN\r\n", (long)desc->inet.port)); + DEBUGF(("tcp_inet_ctl(%p): FDOPEN\r\n", + desc->inet.port)); if (!IS_CONNECTED(INETP(desc))) { return ctl_error(ENOTCONN, rbuf, rsize); } @@ -10367,12 +10461,20 @@ static ErlDrvSSizeT tcp_inet_ctl(ErlDrvData e, unsigned int cmd, int raw_file_fd; - DEBUGF(("tcp_inet_ctl(%ld): SENDFILE\r\n", (long)desc->inet.port)); + DEBUGF(("tcp_inet_ctl(%p): SENDFILE\r\n", + desc->inet.port)); if (len != required_len) { return ctl_error(EINVAL, rbuf, rsize); } else if (!IS_CONNECTED(INETP(desc))) { return ctl_error(ENOTCONN, rbuf, rsize); + } else if (desc->tcp_add_flags & TCP_ADDF_SENDFILE) { + /* This should not happen as prim_inet.erl makes + sure that only the controlling process can + use the sendfile operation. But we add this + check here anyways just in case that prim_inet + is changed... */ + return ctl_error(EINVAL, rbuf, rsize); } sys_memcpy(&raw_file_fd, buf, sizeof(raw_file_fd)); @@ -10380,6 +10482,9 @@ static ErlDrvSSizeT tcp_inet_ctl(ErlDrvData e, unsigned int cmd, desc->sendfile.dup_file_fd = dup(raw_file_fd); + DEBUGF(("tcp_inet_ctl(%p): SENDFILE dup %d\r\n", + desc->inet.port, desc->sendfile.dup_file_fd)); + if(desc->sendfile.dup_file_fd == -1) { return ctl_error(errno, rbuf, rsize); } @@ -10412,7 +10517,8 @@ static ErlDrvSSizeT tcp_inet_ctl(ErlDrvData e, unsigned int cmd, } default: - DEBUGF(("tcp_inet_ctl(%ld): %u\r\n", (long)desc->inet.port, cmd)); + DEBUGF(("tcp_inet_ctl(%p): %u\r\n", + desc->inet.port, cmd)); return inet_ctl(INETP(desc), cmd, buf, len, rbuf, rsize); } @@ -10431,6 +10537,11 @@ static void tcp_inet_send_timeout(ErlDrvData e, ErlDrvTermData dummy) if (desc->send_timeout_close) { tcp_desc_close(desc); } + /* Q: Why not keep port busy as send queue may still be full (ERL-1390)? + * + * A: If kept busy, a following send call would hang without a timeout + * as it would get suspended in erlang:port_command waiting on busy port. + */ } /* @@ -10449,8 +10560,8 @@ static void tcp_inet_timeout(ErlDrvData e) tcp_descriptor* desc = (tcp_descriptor*)e; int state = desc->inet.state; - DEBUGF(("tcp_inet_timeout(%ld) {s=%d\r\n", - (long)desc->inet.port, desc->inet.s)); + DEBUGF(("tcp_inet_timeout(%p) {s=%d\r\n", + desc->inet.port, desc->inet.s)); if ((state & INET_F_MULTI_CLIENT)) { /* Multi-client always means multi-timers */ fire_multi_timers(desc, desc->inet.port, e); } else if ((state & INET_STATE_CONNECTED) == INET_STATE_CONNECTED) { @@ -10472,7 +10583,7 @@ static void tcp_inet_timeout(ErlDrvData e) desc->inet.state = INET_STATE_LISTENING; async_error_am(INETP(desc), am_timeout); } - DEBUGF(("tcp_inet_timeout(%ld) }\r\n", (long)desc->inet.port)); + DEBUGF(("tcp_inet_timeout(%p) }\r\n", desc->inet.port)); } static void tcp_inet_multi_timeout(ErlDrvData e, ErlDrvTermData caller) @@ -10508,13 +10619,13 @@ static void tcp_inet_command(ErlDrvData e, char *buf, ErlDrvSizeT len) tcp_descriptor* desc = (tcp_descriptor*)e; desc->inet.caller = driver_caller(desc->inet.port); - DEBUGF(("tcp_inet_command(%ld) {s=%d\r\n", - (long)desc->inet.port, desc->inet.s)); + DEBUGF(("tcp_inet_command(%p) {s=%d\r\n", + desc->inet.port, desc->inet.s)); if (!IS_CONNECTED(INETP(desc))) inet_reply_error(INETP(desc), ENOTCONN); else if (tcp_send(desc, buf, len) == 0) inet_reply_ok(INETP(desc)); - DEBUGF(("tcp_inet_command(%ld) }\r\n", (long)desc->inet.port)); + DEBUGF(("tcp_inet_command(%p) }\r\n", desc->inet.port)); } static void tcp_inet_commandv(ErlDrvData e, ErlIOVec* ev) @@ -10522,8 +10633,8 @@ static void tcp_inet_commandv(ErlDrvData e, ErlIOVec* ev) tcp_descriptor* desc = (tcp_descriptor*)e; desc->inet.caller = driver_caller(desc->inet.port); - DEBUGF(("tcp_inet_commanv(%ld) {s=%d\r\n", - (long)desc->inet.port, desc->inet.s)); + DEBUGF(("tcp_inet_commanv(%p) {s=%d\r\n", + desc->inet.port, desc->inet.s)); if (!IS_CONNECTED(INETP(desc))) { if (desc->tcp_add_flags & TCP_ADDF_DELAYED_CLOSE_SEND) { desc->tcp_add_flags &= ~TCP_ADDF_DELAYED_CLOSE_SEND; @@ -10542,7 +10653,7 @@ static void tcp_inet_commandv(ErlDrvData e, ErlIOVec* ev) tcp_shutdown_error(desc, EPIPE); else if (tcp_sendv(desc, ev) == 0) inet_reply_ok(INETP(desc)); - DEBUGF(("tcp_inet_commandv(%ld) }\r\n", (long)desc->inet.port)); + DEBUGF(("tcp_inet_commandv(%p) }\r\n", desc->inet.port)); } static void tcp_inet_flush(ErlDrvData e) @@ -10557,11 +10668,9 @@ static void tcp_inet_flush(ErlDrvData e) #ifdef HAVE_SENDFILE /* The old file driver aborted when it was stopped during sendfile, so - * we'll clear the flag and discard all output. */ + * we'll clear the flag and discard all output. It is the job of + * tcp_inet_stop to close the extra sendfile fd. */ if(desc->tcp_add_flags & TCP_ADDF_SENDFILE) { - desc->tcp_add_flags &= ~TCP_ADDF_SENDFILE; - close(desc->sendfile.dup_file_fd); - discard_output = 1; } #endif @@ -10613,10 +10722,10 @@ static void inet_stop_select(ErlDrvEvent event, void* _) static int tcp_recv_closed(tcp_descriptor* desc) { #ifdef DEBUG - long port = (long) desc->inet.port; /* Used after driver_exit() */ + ErlDrvPort port = desc->inet.port; /* Used after driver_exit() */ #endif int blocking_send = 0; - DEBUGF(("tcp_recv_closed(%ld): s=%d, in %s, line %d\r\n", + DEBUGF(("tcp_recv_closed(%p): s=%d, in %s, line %d\r\n", port, desc->inet.s, __FILE__, __LINE__)); if (IS_BUSY(INETP(desc))) { /* A send is blocked */ @@ -10625,12 +10734,12 @@ static int tcp_recv_closed(tcp_descriptor* desc) if (desc->busy_on_send) { cancel_multi_timer(desc, INETP(desc)->port, &tcp_inet_send_timeout); desc->busy_on_send = 0; - DEBUGF(("tcp_recv_closed(%ld): busy on send\r\n", port)); + DEBUGF(("tcp_recv_closed(%p): busy on send\r\n", port)); } desc->inet.state &= ~INET_F_BUSY; set_busy_port(desc->inet.port, 0); inet_reply_error_am(INETP(desc), am_closed); - DEBUGF(("tcp_recv_closed(%ld): busy reply 'closed'\r\n", port)); + DEBUGF(("tcp_recv_closed(%p): busy reply 'closed'\r\n", port)); blocking_send = 1; } #ifdef HAVE_SENDFILE @@ -10659,7 +10768,8 @@ static int tcp_recv_closed(tcp_descriptor* desc) } async_error_am_all(INETP(desc), am_closed); /* next time EXBADSEQ will be delivered */ - DEBUGF(("tcp_recv_closed(%ld): passive reply all 'closed'\r\n", port)); + DEBUGF(("tcp_recv_closed(%p): passive reply all 'closed'\r\n", + port)); } else { tcp_clear_input(desc); tcp_closed_message(desc); @@ -10668,9 +10778,9 @@ static int tcp_recv_closed(tcp_descriptor* desc) } else { desc_close_read(INETP(desc)); } - DEBUGF(("tcp_recv_closed(%ld): active close\r\n", port)); + DEBUGF(("tcp_recv_closed(%p): active close\r\n", port)); } - DEBUGF(("tcp_recv_closed(%ld): done\r\n", port)); + DEBUGF(("tcp_recv_closed(%p): done\r\n", port)); return -1; } @@ -10747,8 +10857,8 @@ static int tcp_remain(tcp_descriptor* desc, int* len) desc->inet.psize, desc->i_bufsz, desc->inet.delimiter, &desc->http_state); - DEBUGF(("tcp_remain(%ld): s=%d, n=%d, nfill=%d nsz=%d, tlen %d\r\n", - (long)desc->inet.port, desc->inet.s, n, nfill, nsz, tlen)); + DEBUGF(("tcp_remain(%p): s=%d, n=%d, nfill=%d nsz=%d, tlen %d\r\n", + desc->inet.port, desc->inet.s, n, nfill, nsz, tlen)); if (tlen > 0) { if (tlen <= n) { /* got a packet */ @@ -10924,8 +11034,8 @@ static int tcp_recv(tcp_descriptor* desc, int request_len) else /* remain already set use it */ nread = desc->i_remain; - DEBUGF(("tcp_recv(%ld): s=%d about to read %d bytes...\r\n", - (long)desc->inet.port, desc->inet.s, nread)); + DEBUGF(("tcp_recv(%p): s=%d about to read %d bytes...\r\n", + desc->inet.port, desc->inet.s, nread)); n = sock_recv(desc->inet.s, desc->i_ptr, nread, 0); @@ -11079,8 +11189,8 @@ static void tcp_inet_event(ErlDrvData e, ErlDrvEvent event) WSANETWORKEVENTS netEv; int err; - DEBUGF(("tcp_inet_event(%ld) {s=%d\r\n", - (long)desc->inet.port, desc->inet.s)); + DEBUGF(("tcp_inet_event(%p) {s=%d\r\n", + desc->inet.port, desc->inet.s)); if (WSAEnumNetworkEvents(desc->inet.s, desc->inet.event, &netEv) != 0) { DEBUGF((" => EnumNetworkEvents = %d\r\n", sock_errno() )); @@ -11179,11 +11289,12 @@ static void tcp_inet_event(ErlDrvData e, ErlDrvEvent event) else tcp_recv_closed(desc); } - DEBUGF(("tcp_inet_event(%ld) }\r\n", (long)desc->inet.port)); + DEBUGF(("tcp_inet_event(%p) }\r\n", desc->inet.port)); return; error: - DEBUGF(("tcp_inet_event(%ld) error}\r\n", (long)desc->inet.port)); + DEBUGF(("tcp_inet_event(%p) error}\r\n", + desc->inet.port)); return; } @@ -11201,8 +11312,8 @@ static int tcp_inet_input(tcp_descriptor* desc, HANDLE event) long port = (long) desc->inet.port; /* Used after driver_exit() */ #endif ASSERT(!INET_IGNORED(INETP(desc))); - DEBUGF(("tcp_inet_input(%ld) {s=%d\r\n", port, desc->inet.s)); - /* XXX fprintf(stderr,"tcp_inet_input(%ld) {s=%d}\r\n",(long) desc->inet.port, desc->inet.s); */ + DEBUGF(("tcp_inet_input(%p) {s=%d\r\n", port, desc->inet.s)); + /* XXX fprintf(stderr,"tcp_inet_input(%p) {s=%d}\r\n",(long) desc->inet.port, desc->inet.s); */ if (desc->inet.state == INET_STATE_ACCEPTING) { SOCKET s; unsigned int len; @@ -11339,11 +11450,11 @@ static int tcp_inet_input(tcp_descriptor* desc, HANDLE event) else { /* maybe a close op from connection attempt?? */ sock_select(INETP(desc),FD_ACCEPT,0); - DEBUGF(("tcp_inet_input(%ld): s=%d bad state: %04x\r\n", + DEBUGF(("tcp_inet_input(%p): s=%d bad state: %04x\r\n", port, desc->inet.s, desc->inet.state)); } done: - DEBUGF(("tcp_inet_input(%ld) }\r\n", port)); + DEBUGF(("tcp_inet_input(%p) }\r\n", port)); return ret; } @@ -11371,8 +11482,8 @@ static int tcp_send_or_shutdown_error(tcp_descriptor* desc, int err) * socket option is enabled). We just have to distinguish between passive * and active sockets. */ - DEBUGF(("driver_failure_eof(%ld) in %s, line %d\r\n", - (long)desc->inet.port, __FILE__, __LINE__)); + DEBUGF(("driver_failure_eof(%p) in %s, line %d\r\n", + desc->inet.port, __FILE__, __LINE__)); if (desc->inet.active) { ErlDrvTermData err_atom; if (show_econnreset) { @@ -11515,8 +11626,8 @@ static int tcp_sendv(tcp_descriptor* desc, ErlIOVec* ev) if ((desc->tcp_add_flags & TCP_ADDF_SENDFILE) || sz > 0) { driver_enqv(ix, ev, 0); if (sz+ev->size >= desc->high) { - DEBUGF(("tcp_sendv(%ld): s=%d, sender forced busy\r\n", - (long)desc->inet.port, desc->inet.s)); + DEBUGF(("tcp_sendv(%p): s=%d, sender forced busy\r\n", + desc->inet.port, desc->inet.s)); desc->inet.state |= INET_F_BUSY; /* mark for low-watermark */ desc->inet.busy_caller = desc->inet.caller; set_busy_port(desc->inet.port, 1); @@ -11532,8 +11643,10 @@ static int tcp_sendv(tcp_descriptor* desc, ErlIOVec* ev) else { int vsize = (ev->vsize > MAX_VSIZE) ? MAX_VSIZE : ev->vsize; - DEBUGF(("tcp_sendv(%ld): s=%d, about to send "LLU","LLU" bytes\r\n", - (long)desc->inet.port, desc->inet.s, (llu_t)h_len, (llu_t)len)); + DEBUGF(("tcp_sendv(%p): s=%d, " + "about to send "LLU","LLU" bytes\r\n", + desc->inet.port, desc->inet.s, + (llu_t)h_len, (llu_t)len)); if (INET_IGNORED(INETP(desc))) { INETP(desc)->flags |= INET_IGNORE_WRITE; @@ -11547,9 +11660,9 @@ static int tcp_sendv(tcp_descriptor* desc, ErlIOVec* ev) vsize, &n, 0))) { if ((sock_errno() != ERRNO_BLOCK) && (sock_errno() != EINTR)) { int err = sock_errno(); - DEBUGF(("tcp_sendv(%ld): s=%d, " + DEBUGF(("tcp_sendv(%p): s=%d, " "sock_sendv(size=2) errno = %d\r\n", - (long)desc->inet.port, desc->inet.s, err)); + desc->inet.port, desc->inet.s, err)); return tcp_send_error(desc, err); } #ifdef __WIN32__ @@ -11562,14 +11675,14 @@ static int tcp_sendv(tcp_descriptor* desc, ErlIOVec* ev) return 0; } else { - DEBUGF(("tcp_sendv(%ld): s=%d, only sent " + DEBUGF(("tcp_sendv(%p): s=%d, only sent " LLU"/%d of "LLU"/%d bytes/items\r\n", - (long)desc->inet.port, desc->inet.s, + desc->inet.port, desc->inet.s, (llu_t)n, vsize, (llu_t)ev->size, ev->vsize)); } - DEBUGF(("tcp_sendv(%ld): s=%d, Send failed, queuing\r\n", - (long)desc->inet.port, desc->inet.s)); + DEBUGF(("tcp_sendv(%p): s=%d, Send failed, queuing\r\n", + desc->inet.port, desc->inet.s)); driver_enqv(ix, ev, n); if (!INET_IGNORED(INETP(desc))) sock_select(INETP(desc),(FD_WRITE|FD_CLOSE), 1); @@ -11618,8 +11731,8 @@ static int tcp_send(tcp_descriptor* desc, char* ptr, ErlDrvSizeT len) driver_enq(ix, buf, h_len); driver_enq(ix, ptr, len); if (sz+h_len+len >= desc->high) { - DEBUGF(("tcp_send(%ld): s=%d, sender forced busy\r\n", - (long)desc->inet.port, desc->inet.s)); + DEBUGF(("tcp_send(%p): s=%d, sender forced busy\r\n", + desc->inet.port, desc->inet.s)); desc->inet.state |= INET_F_BUSY; /* mark for low-watermark */ desc->inet.busy_caller = desc->inet.caller; set_busy_port(desc->inet.port, 1); @@ -11638,8 +11751,10 @@ static int tcp_send(tcp_descriptor* desc, char* ptr, ErlDrvSizeT len) iov[1].iov_base = ptr; iov[1].iov_len = len; - DEBUGF(("tcp_send(%ld): s=%d, about to send "LLU","LLU" bytes\r\n", - (long)desc->inet.port, desc->inet.s, (llu_t)h_len, (llu_t)len)); + DEBUGF(("tcp_send(%p): s=%d, " + "about to send "LLU","LLU" bytes\r\n", + desc->inet.port, desc->inet.s, + (llu_t)h_len, (llu_t)len)); if (INET_IGNORED(INETP(desc))) { INETP(desc)->flags |= INET_IGNORE_WRITE; n = 0; @@ -11649,8 +11764,9 @@ static int tcp_send(tcp_descriptor* desc, char* ptr, ErlDrvSizeT len) } else if (IS_SOCKET_ERROR(sock_sendv(desc->inet.s,iov,2,&n,0))) { if ((sock_errno() != ERRNO_BLOCK) && (sock_errno() != EINTR)) { int err = sock_errno(); - DEBUGF(("tcp_send(%ld): s=%d,sock_sendv(size=2) errno = %d\r\n", - (long)desc->inet.port, desc->inet.s, err)); + DEBUGF(("tcp_send(%p): s=%d, " + "sock_sendv(size=2) errno = %d\r\n", + desc->inet.port, desc->inet.s, err)); return tcp_send_error(desc, err); } #ifdef __WIN32__ @@ -11663,8 +11779,8 @@ static int tcp_send(tcp_descriptor* desc, char* ptr, ErlDrvSizeT len) return 0; } - DEBUGF(("tcp_send(%ld): s=%d, Send failed, queuing", - (long)desc->inet.port, desc->inet.s)); + DEBUGF(("tcp_send(%p): s=%d, Send failed, queuing", + desc->inet.port, desc->inet.s)); if (n < h_len) { driver_enq(ix, buf+n, h_len-n); @@ -11715,6 +11831,9 @@ static int tcp_sendfile_completed(tcp_descriptor* desc) { desc->tcp_add_flags &= ~TCP_ADDF_SENDFILE; close(desc->sendfile.dup_file_fd); + DEBUGF(("tcp_sendfile_completed(%p): SENDFILE dup closed %d\r\n", + desc->inet.port, desc->sendfile.dup_file_fd)); + /* While we flushed the output queue prior to sending the file, we've * deferred clearing busy status until now as there's no point in doing so * while we still have a file to send. @@ -11799,7 +11918,8 @@ static int tcp_inet_sendfile(tcp_descriptor* desc) { int result = 0; ssize_t n; - DEBUGF(("tcp_inet_sendfile(%ld) {s=%d\r\n", (long)ix, desc->inet.s)); + DEBUGF(("tcp_inet_sendfile(%p) {s=%d\r\n", + ix, desc->inet.s)); /* If there was any data in the queue by the time sendfile was issued, * we'll need to skip it first. Note that we don't clear busy status until @@ -11931,8 +12051,8 @@ static int tcp_inet_sendfile(tcp_descriptor* desc) { socket_error: { int socket_errno = sock_errno(); - DEBUGF(("tcp_inet_sendfile(%ld): send errno = %d (errno %d)\r\n", - (long)desc->inet.port, socket_errno, errno)); + DEBUGF(("tcp_inet_sendfile(%p): send errno = %d (errno %d)\r\n", + desc->inet.port, socket_errno, errno)); tcp_sendfile_aborted(desc, socket_errno); result = tcp_send_error(desc, socket_errno); @@ -11941,7 +12061,7 @@ socket_error: { } done: - DEBUGF(("tcp_inet_sendfile(%ld) }\r\n", (long)desc->inet.port)); + DEBUGF(("tcp_inet_sendfile(%p) }\r\n", desc->inet.port)); return result; } #endif /* HAVE_SENDFILE */ @@ -11956,8 +12076,8 @@ static int tcp_inet_output(tcp_descriptor* desc, HANDLE event) ErlDrvPort ix = desc->inet.port; ASSERT(!INET_IGNORED(INETP(desc))); - DEBUGF(("tcp_inet_output(%ld) {s=%d\r\n", - (long)desc->inet.port, desc->inet.s)); + DEBUGF(("tcp_inet_output(%p) {s=%d\r\n", + desc->inet.port, desc->inet.s)); if (desc->inet.state == INET_STATE_CONNECTING) { sock_select(INETP(desc),FD_CONNECT,0); @@ -12026,13 +12146,16 @@ static int tcp_inet_output(tcp_descriptor* desc, HANDLE event) goto done; } vsize = vsize > MAX_VSIZE ? MAX_VSIZE : vsize; - DEBUGF(("tcp_inet_output(%ld): s=%d, About to send %d items\r\n", - (long)desc->inet.port, desc->inet.s, vsize)); + DEBUGF(("tcp_inet_output(%p): s=%d, " + "About to send %d items\r\n", + desc->inet.port, desc->inet.s, vsize)); if (IS_SOCKET_ERROR(sock_sendv(desc->inet.s, iov, vsize, &n, 0))) { write_error: if ((sock_errno() != ERRNO_BLOCK) && (sock_errno() != EINTR)) { - DEBUGF(("tcp_inet_output(%ld): sock_sendv(%d) errno = %d (errno %d)\r\n", - (long)desc->inet.port, vsize, sock_errno(), errno)); + DEBUGF(("tcp_inet_output(%p): " + "sock_sendv(%d) errno = %d (errno %d)\r\n", + desc->inet.port, vsize, + sock_errno(), errno)); ret = tcp_send_error(desc, sock_errno()); goto done; } @@ -12080,11 +12203,11 @@ static int tcp_inet_output(tcp_descriptor* desc, HANDLE event) } else { sock_select(INETP(desc),FD_CONNECT,0); - DEBUGF(("tcp_inet_output(%ld): bad state: %04x\r\n", - (long)desc->inet.port, desc->inet.state)); + DEBUGF(("tcp_inet_output(%p): bad state: %04x\r\n", + desc->inet.port, desc->inet.state)); } done: - DEBUGF(("tcp_inet_output(%ld) }\r\n", (long)desc->inet.port)); + DEBUGF(("tcp_inet_output(%p) }\r\n", desc->inet.port)); return ret; } @@ -12246,14 +12369,15 @@ static void packet_inet_stop(ErlDrvData e) into "udp_descriptor*" or "inet_descriptor*": */ udp_descriptor * udesc = (udp_descriptor*) e; - inet_descriptor* descr = INETP(udesc); + inet_descriptor* desc = INETP(udesc); if (udesc->i_buf != NULL) { release_buffer(udesc->i_buf); udesc->i_buf = NULL; } - ASSERT(NO_SUBSCRIBERS(&(descr->empty_out_q_subs))); - inet_stop(descr); + ASSERT(NO_SUBSCRIBERS(&(desc->empty_out_q_subs))); + async_error_am_all(desc, am_closed); + inet_stop(desc); } static int packet_error(udp_descriptor* udesc, int err) @@ -12280,7 +12404,8 @@ static ErlDrvSSizeT packet_inet_ctl(ErlDrvData e, unsigned int cmd, char* buf, cmd -= ERTS_INET_DRV_CONTROL_MAGIC_NUMBER; switch(cmd) { case INET_REQ_OPEN: /* open socket and return internal index */ - DEBUGF(("packet_inet_ctl(%ld): OPEN\r\n", (long)desc->port)); + DEBUGF(("packet_inet_ctl(%p): OPEN\r\n", + desc->port)); if (len != 2) { return ctl_error(EINVAL, rbuf, rsize); } @@ -12329,7 +12454,8 @@ static ErlDrvSSizeT packet_inet_ctl(ErlDrvData e, unsigned int cmd, char* buf, case INET_REQ_FDOPEN: { /* pass in an open (and optionally bound) socket */ SOCKET s; int bound; - DEBUGF(("packet inet_ctl(%ld): FDOPEN\r\n", (long)desc->port)); + DEBUGF(("packet inet_ctl(%p): FDOPEN\r\n", + desc->port)); if (len != 6 && len != 10) { return ctl_error(EINVAL, rbuf, rsize); } @@ -12382,7 +12508,8 @@ static ErlDrvSSizeT packet_inet_ctl(ErlDrvData e, unsigned int cmd, char* buf, case INET_REQ_CLOSE: - DEBUGF(("packet_inet_ctl(%ld): CLOSE\r\n", (long)desc->port)); + DEBUGF(("packet_inet_ctl(%p): CLOSE\r\n", + desc->port)); erl_inet_close(desc); return ctl_reply(INET_REP_OK, NULL, 0, rbuf, rsize); @@ -12400,7 +12527,8 @@ static ErlDrvSSizeT packet_inet_ctl(ErlDrvData e, unsigned int cmd, char* buf, #ifdef HAVE_SCTP unsigned timeout; #endif - DEBUGF(("packet_inet_ctl(%ld): CONNECT\r\n", (long)desc->port)); + DEBUGF(("packet_inet_ctl(%p): CONNECT\r\n", + desc->port)); /* INPUT: [ Timeout(4), Port(2), Address(N) ] */ @@ -12487,7 +12615,8 @@ static ErlDrvSSizeT packet_inet_ctl(ErlDrvData e, unsigned int cmd, char* buf, */ int backlog; - DEBUGF(("packet_inet_ctl(%ld): LISTEN\r\n", (long)desc->port)); + DEBUGF(("packet_inet_ctl(%p): LISTEN\r\n", + desc->port)); if (!IS_SCTP(desc)) return ctl_xerror(EXBADPORT, rbuf, rsize); if (!IS_OPEN(desc)) @@ -12552,7 +12681,8 @@ static ErlDrvSSizeT packet_inet_ctl(ErlDrvData e, unsigned int cmd, char* buf, int err; SOCKET new_socket; - DEBUGF(("packet_inet_ctl(%ld): PEELOFF\r\n", (long)desc->port)); + DEBUGF(("packet_inet_ctl(%p): PEELOFF\r\n", + desc->port)); if (!IS_SCTP(desc)) return ctl_xerror(EXBADPORT, rbuf, rsize); if (!IS_OPEN(desc)) @@ -12593,7 +12723,8 @@ static ErlDrvSSizeT packet_inet_ctl(ErlDrvData e, unsigned int cmd, char* buf, unsigned timeout; char tbuf[2]; - DEBUGF(("packet_inet_ctl(%ld): RECV\r\n", (long)desc->port)); + DEBUGF(("packet_inet_ctl(%p): RECV\r\n", + desc->port)); /* INPUT: Timeout(4), Length(4) */ if (!IS_OPEN(desc)) return ctl_xerror(EXBADPORT, rbuf, rsize); |