Skip to content

Commit 94b7171

Browse files
committed
Implement TCP_USER_TIMEOUT for socket
Update the documentation to mention this option and some other that were overlooked.
1 parent 94a2e93 commit 94b7171

File tree

4 files changed

+112
-11
lines changed

4 files changed

+112
-11
lines changed

erts/emulator/nifs/common/prim_socket_int.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -567,6 +567,11 @@ extern BOOLEAN_T esock_getopt_int(SOCKET sock,
567567
int opt,
568568
int* valP);
569569

570+
extern BOOLEAN_T esock_getopt_uint(SOCKET sock,
571+
int level,
572+
int opt,
573+
unsigned int *valP);
574+
570575

571576
/* ** Socket Registry functions *** */
572577
extern void esock_send_reg_add_msg(ErlNifEnv* env,

erts/emulator/nifs/common/prim_socket_nif.c

Lines changed: 84 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1310,6 +1310,10 @@ static ERL_NIF_TERM esock_getopt_int_opt(ErlNifEnv* env,
13101310
ESockDescriptor* descP,
13111311
int level,
13121312
int opt);
1313+
static ERL_NIF_TERM esock_getopt_uint_opt(ErlNifEnv* env,
1314+
ESockDescriptor* descP,
1315+
int level,
1316+
int opt);
13131317
static ERL_NIF_TERM esock_getopt_size_opt(ErlNifEnv* env,
13141318
ESockDescriptor* descP,
13151319
int level,
@@ -1719,6 +1723,11 @@ static ERL_NIF_TERM esock_setopt_int_opt(ErlNifEnv* env,
17191723
int level,
17201724
int opt,
17211725
ERL_NIF_TERM eVal);
1726+
static ERL_NIF_TERM esock_setopt_uint_opt(ErlNifEnv* env,
1727+
ESockDescriptor* descP,
1728+
int level,
1729+
int opt,
1730+
ERL_NIF_TERM eVal);
17221731
#if (defined(SO_RCVTIMEO) || defined(SO_SNDTIMEO)) \
17231732
&& defined(ESOCK_USE_RCVSNDTIMEO)
17241733
static ERL_NIF_TERM esock_setopt_timeval_opt(ErlNifEnv* env,
@@ -3762,7 +3771,14 @@ static struct ESockOpt optLevelTCP[] =
37623771
#endif
37633772
&esock_atom_nopush},
37643773
{0, NULL, NULL, &esock_atom_syncnt},
3765-
{0, NULL, NULL, &esock_atom_user_timeout}
3774+
{
3775+
#ifdef TCP_USER_TIMEOUT
3776+
TCP_USER_TIMEOUT,
3777+
esock_setopt_uint_opt, esock_getopt_uint_opt,
3778+
#else
3779+
0, NULL, NULL,
3780+
#endif
3781+
&esock_atom_user_timeout}
37663782

37673783
};
37683784

@@ -8286,6 +8302,31 @@ ERL_NIF_TERM esock_setopt_int_opt(ErlNifEnv* env,
82868302

82878303

82888304

8305+
/* esock_setopt_uint_opt - set an option that has an unsigned integer value
8306+
*/
8307+
8308+
static
8309+
ERL_NIF_TERM esock_setopt_uint_opt(ErlNifEnv* env,
8310+
ESockDescriptor* descP,
8311+
int level,
8312+
int opt,
8313+
ERL_NIF_TERM eVal)
8314+
{
8315+
ERL_NIF_TERM result;
8316+
unsigned int val;
8317+
8318+
if (GET_UINT(env, eVal, &val)) {
8319+
result =
8320+
esock_setopt_level_opt(env, descP, level, opt,
8321+
&val, sizeof(val));
8322+
} else {
8323+
result = esock_make_invalid(env, esock_atom_value);
8324+
}
8325+
return result;
8326+
}
8327+
8328+
8329+
82898330
/* esock_setopt_str_opt - set an option that has an string value
82908331
*/
82918332

@@ -9892,6 +9933,24 @@ ERL_NIF_TERM esock_getopt_int_opt(ErlNifEnv* env,
98929933

98939934

98949935

9936+
/* esock_getopt_uint_opt - get an unsigned integer option
9937+
*/
9938+
static
9939+
ERL_NIF_TERM esock_getopt_uint_opt(ErlNifEnv* env,
9940+
ESockDescriptor* descP,
9941+
int level,
9942+
int opt)
9943+
{
9944+
unsigned int val;
9945+
9946+
if (! esock_getopt_uint(descP->sock, level, opt, &val))
9947+
return esock_make_error_errno(env, sock_errno());
9948+
9949+
return esock_make_ok2(env, MKUI(env, val));
9950+
}
9951+
9952+
9953+
98959954
/* esock_getopt_int - get an integer option
98969955
*/
98979956
extern
@@ -9916,6 +9975,30 @@ BOOLEAN_T esock_getopt_int(SOCKET sock,
99169975

99179976

99189977

9978+
/* esock_getopt_uint - get an unsigned integer option
9979+
*/
9980+
extern
9981+
BOOLEAN_T esock_getopt_uint(SOCKET sock,
9982+
int level,
9983+
int opt,
9984+
unsigned int *valP)
9985+
{
9986+
unsigned int val = 0;
9987+
SOCKOPTLEN_T valSz = sizeof(val);
9988+
9989+
#ifdef __WIN32__
9990+
if (sock_getopt(sock, level, opt, (char*) &val, &valSz) != 0)
9991+
#else
9992+
if (sock_getopt(sock, level, opt, &val, &valSz) != 0)
9993+
#endif
9994+
return FALSE;
9995+
9996+
*valP = val;
9997+
return TRUE;
9998+
}
9999+
10000+
10001+
991910002
static
992010003
ERL_NIF_TERM esock_getopt_size_opt(ErlNifEnv* env,
992110004
ESockDescriptor* descP,

lib/kernel/doc/guides/socket_usage.md

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -626,16 +626,19 @@ _Table: ipv6 options_
626626
[](){: #socket_options_tcp }
627627
Options for level `tcp`:
628628

629-
| Option Name | Value Type | Set | Get | Other Requirements and comments |
630-
| ----------- | ---------- | --- | --- | -------------------------------------------------------------------------------------------------------- |
631-
| congestion | string() | yes | yes | none |
632-
| cork | boolean() | yes | yes | 'nopush' one some platforms (FreeBSD) |
633-
| keepcnt | integer() | yes | yes | On Windows (at least), it is illegal to set to a value greater than 255. |
634-
| keepidle | integer() | yes | yes | none |
635-
| keepintvl | integer() | yes | yes | none |
636-
| maxseg | integer() | yes | yes | Set not allowed on all platforms. |
637-
| nodelay | boolean() | yes | yes | none |
638-
| nopush | boolean() | yes | yes | 'cork' on some platforms (Linux). On Darwin this has a different meaning than on, for instance, FreeBSD. |
629+
| Option Name | Value Type | Set | Get | Other Requirements and comments |
630+
| ------------ | -------------- | --- | --- | ---------------------------------------------------- |
631+
| congestion | string() | yes | yes | none |
632+
| cork | boolean() | yes | yes | 'nopush' one some platforms (FreeBSD) |
633+
| keepcnt | integer() | yes | yes | On Windows (at least), it is illegal to set to |
634+
| | | | | a value greater than 255. |
635+
| keepidle | integer() | yes | yes | none |
636+
| keepintvl | integer() | yes | yes | none |
637+
| maxseg | integer() | yes | yes | Set not allowed on all platforms. |
638+
| nodelay | boolean() | yes | yes | none |
639+
| nopush | boolean() | yes | yes | 'cork' on some platforms (Linux). On Darwin this has |
640+
| | | | | a different meaning than on, for instance, FreeBSD. |
641+
| user_timeout | integer() >= 0 | yes | yes | none |
639642

640643
_Table: tcp options_
641644

lib/kernel/src/socket.erl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1266,10 +1266,20 @@ _Options for protocol level_ [_`tcp`:_](`t:level/0`)
12661266

12671267
- **`{tcp, cork}`** - `Value = boolean()`
12681268

1269+
- **`{tcp, keepcnt}`** - `Value = integer()`
1270+
1271+
- **`{tcp, keepidle}`** - `Value = integer()`
1272+
1273+
- **`{tcp, keepintvl}`** - `Value = integer()`
1274+
12691275
- **`{tcp, maxseg}`** - `Value = integer()`
12701276

12711277
- **`{tcp, nodelay}`** - `Value = boolean()`
12721278

1279+
- **`{tcp, nopush}`** - `Value = boolean()`
1280+
1281+
- **`{tcp, user_timeout}`** - `Value = non_neg_integer()`
1282+
12731283
_Options for protocol level_ [_`udp`:_](`t:level/0`)
12741284

12751285
- **`{udp, cork}`** - `Value = boolean()`

0 commit comments

Comments
 (0)