@@ -767,6 +767,13 @@ static size_t my_strnlen(const char *s, size_t maxlen)
767767#define INET_TYPE_DGRAM 2
768768#define INET_TYPE_SEQPACKET 3
769769
770+ /* open protocol */
771+ #define INET_PROTO_DEFAULT 0
772+ #define INET_PROTO_TCP 1
773+ #define INET_PROTO_UDP 2
774+ #define INET_PROTO_SCTP 3
775+ #define INET_PROTO_MPTCP 4
776+
770777/* INET_LOPT_MODE options */
771778#define INET_MODE_LIST 0
772779#define INET_MODE_BINARY 1
@@ -1611,6 +1618,7 @@ static ErlDrvTermData am_sendfile;
16111618#endif
16121619
16131620static char str_eafnosupport [] = "eafnosupport" ;
1621+ static char str_eprotonosupport [] = "eprotonosupport" ;
16141622static char str_einval [] = "einval" ;
16151623
16161624/* special errors for bad ports and sequences */
@@ -5078,11 +5086,12 @@ static int erl_inet_close(inet_descriptor* desc)
50785086 return 0 ;
50795087}
50805088
5081- static ErlDrvSSizeT inet_ctl_open (inet_descriptor * desc , int domain , int type ,
5082- char * * rbuf , ErlDrvSizeT rsize )
5089+ static
5090+ ErlDrvSSizeT inet_ctl_open (inet_descriptor * desc ,
5091+ int domain , int type , int protocol ,
5092+ char * * rbuf , ErlDrvSizeT rsize )
50835093{
50845094 int save_errno ;
5085- int protocol ;
50865095#ifdef HAVE_SETNS
50875096 int current_ns , new_ns ;
50885097 current_ns = new_ns = 0 ;
@@ -5125,7 +5134,6 @@ static ErlDrvSSizeT inet_ctl_open(inet_descriptor* desc, int domain, int type,
51255134 }
51265135 }
51275136#endif
5128- protocol = desc -> sprotocol ;
51295137#ifdef HAVE_SYS_UN_H
51305138 if (domain == AF_UNIX ) protocol = 0 ;
51315139#endif
@@ -11843,13 +11851,13 @@ static ErlDrvSSizeT tcp_inet_ctl(ErlDrvData e, unsigned int cmd,
1184311851 switch (cmd ) {
1184411852
1184511853 case INET_REQ_OPEN : { /* open socket and return internal index */
11846- int domain ;
11854+ int domain , protocol ;
1184711855
1184811856 DDBG (INETP (desc ),
1184911857 ("INET-DRV-DBG[%d][%T] tcp_inet_ctl -> OPEN\r\n" ,
1185011858 __LINE__ , driver_caller (desc -> inet .port )) );
1185111859
11852- if (len != 2 ) return ctl_error (EINVAL , rbuf , rsize );
11860+ if (len != 3 ) return ctl_error (EINVAL , rbuf , rsize );
1185311861 switch (buf [0 ]) {
1185411862 case INET_AF_INET :
1185511863 domain = AF_INET ;
@@ -11868,7 +11876,18 @@ static ErlDrvSSizeT tcp_inet_ctl(ErlDrvData e, unsigned int cmd,
1186811876 return ctl_xerror (str_eafnosupport , rbuf , rsize );
1186911877 }
1187011878 if (buf [1 ] != INET_TYPE_STREAM ) return ctl_error (EINVAL , rbuf , rsize );
11871- return inet_ctl_open (INETP (desc ), domain , SOCK_STREAM , rbuf , rsize );
11879+ switch (buf [2 ]) {
11880+ case INET_PROTO_DEFAULT : protocol = 0 ; break ;
11881+ case INET_PROTO_TCP : protocol = IPPROTO_TCP ; break ;
11882+ #ifdef IPPROTO_MPTCP
11883+ case INET_PROTO_MPTCP : protocol = IPPROTO_MPTCP ; break ;
11884+ #endif
11885+ default :
11886+ return ctl_xerror (str_eprotonosupport , rbuf , rsize );
11887+ }
11888+ return
11889+ inet_ctl_open (INETP (desc ),
11890+ domain , SOCK_STREAM , protocol , rbuf , rsize );
1187211891 break ;
1187311892 }
1187411893
@@ -14360,8 +14379,9 @@ static ErlDrvSSizeT packet_inet_ctl(ErlDrvData e, unsigned int cmd, char* buf,
1436014379 ErlDrvSSizeT replen ;
1436114380 udp_descriptor * udesc = (udp_descriptor * ) e ;
1436214381 inet_descriptor * desc = INETP (udesc );
14363- int type = SOCK_DGRAM ;
1436414382 int af = AF_INET ;
14383+ int type = SOCK_DGRAM ;
14384+ int protocol ;
1436514385
1436614386 cmd -= ERTS_INET_DRV_CONTROL_MAGIC_NUMBER ;
1436714387
@@ -14370,7 +14390,7 @@ static ErlDrvSSizeT packet_inet_ctl(ErlDrvData e, unsigned int cmd, char* buf,
1437014390 DDBG (desc ,
1437114391 ("INET-DRV-DBG[%d][%T] packet_inet_ctl -> OPEN\r\n" ,
1437214392 __LINE__ , driver_caller (desc -> port )) );
14373- if (len != 2 ) {
14393+ if (len != 3 ) {
1437414394 return ctl_error (EINVAL , rbuf , rsize );
1437514395 }
1437614396
@@ -14396,7 +14416,15 @@ static ErlDrvSSizeT packet_inet_ctl(ErlDrvData e, unsigned int cmd, char* buf,
1439614416 return ctl_error (EINVAL , rbuf , rsize );
1439714417 }
1439814418
14399- replen = inet_ctl_open (desc , af , type , rbuf , rsize );
14419+ switch (buf [2 ]) {
14420+ case INET_PROTO_DEFAULT : protocol = 0 ; break ;
14421+ case INET_PROTO_UDP : protocol = IPPROTO_UDP ; break ;
14422+ case INET_PROTO_SCTP : protocol = IPPROTO_SCTP ; break ;
14423+ default :
14424+ return ctl_xerror (str_eprotonosupport , rbuf , rsize );
14425+ }
14426+
14427+ replen = inet_ctl_open (desc , af , type , protocol , rbuf , rsize );
1440014428
1440114429 if ((* rbuf )[0 ] != INET_REP_ERROR ) {
1440214430 if (desc -> active )
0 commit comments