-
-
Notifications
You must be signed in to change notification settings - Fork 35k
net: add setTypeOfService and getTypeOfService to Socket #61503
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
eb53d09
9e7a183
14b3fb0
f339cd0
d32f212
71ecbd7
c0407b2
8439cfd
fe329db
778580a
efb5f88
8dce839
1fb4683
1084571
0a90f1c
603445d
f22a74c
b272fda
c6f1153
fe14b34
041c30a
7516aff
83d875c
c03162b
b884430
c39d13e
98747a7
551a5d3
2bb4591
a2d4c36
b04b62f
569debb
e33561d
d53c015
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -33,7 +33,10 @@ | |
| #include "stream_wrap.h" | ||
| #include "util-inl.h" | ||
|
|
||
| #include <cstdlib> | ||
amyssnippet marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| #ifndef _WIN32 | ||
| #include <sys/socket.h> | ||
| #include <netinet/in.h> | ||
| #endif | ||
|
|
||
|
|
||
| namespace node { | ||
|
|
@@ -106,6 +109,8 @@ void TCPWrap::Initialize(Local<Object> target, | |
| GetSockOrPeerName<TCPWrap, uv_tcp_getpeername>); | ||
| SetProtoMethod(isolate, t, "setNoDelay", SetNoDelay); | ||
| SetProtoMethod(isolate, t, "setKeepAlive", SetKeepAlive); | ||
| SetProtoMethod(isolate, t, "setTOS", SetTOS); | ||
| SetProtoMethod(isolate, t, "getTOS", GetTOS); | ||
| SetProtoMethod(isolate, t, "reset", Reset); | ||
|
|
||
| #ifdef _WIN32 | ||
|
|
@@ -145,6 +150,8 @@ void TCPWrap::RegisterExternalReferences(ExternalReferenceRegistry* registry) { | |
| registry->Register(GetSockOrPeerName<TCPWrap, uv_tcp_getpeername>); | ||
| registry->Register(SetNoDelay); | ||
| registry->Register(SetKeepAlive); | ||
| registry->Register(SetTOS); | ||
| registry->Register(GetTOS); | ||
| registry->Register(Reset); | ||
| #ifdef _WIN32 | ||
| registry->Register(SetSimultaneousAccepts); | ||
|
|
@@ -209,6 +216,78 @@ void TCPWrap::SetKeepAlive(const FunctionCallbackInfo<Value>& args) { | |
| } | ||
|
|
||
|
|
||
| void TCPWrap::SetTOS(const FunctionCallbackInfo<Value>& args) { | ||
| TCPWrap* wrap; | ||
| ASSIGN_OR_RETURN_UNWRAP( | ||
| &wrap, args.This(), args.GetReturnValue().Set(UV_EBADF)); | ||
| Environment* env = wrap->env(); | ||
| int tos; | ||
| if (!args[0]->Int32Value(env->context()).To(&tos)) return; | ||
|
|
||
| int fd; | ||
| int err = uv_fileno(reinterpret_cast<uv_handle_t*>(&wrap->handle_), &fd); | ||
| if (err != 0) { | ||
| args.GetReturnValue().Set(err); | ||
| return; | ||
| } | ||
|
|
||
| #ifdef _WIN32 | ||
| args.GetReturnValue().Set(UV_ENOSYS); | ||
| #else | ||
| // Try IPv4 first | ||
| if (setsockopt(fd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)) == 0) { | ||
| args.GetReturnValue().Set(0); | ||
| return; | ||
| } | ||
|
|
||
| // If IPv4 failed, try IPv6 | ||
| if (setsockopt(fd, IPPROTO_IPV6, IPV6_TCLASS, &tos, sizeof(tos)) == 0) { | ||
| args.GetReturnValue().Set(0); | ||
| return; | ||
| } | ||
|
|
||
| // If both failed, return the negative errno | ||
| args.GetReturnValue().Set(-errno); | ||
amyssnippet marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| #endif | ||
| } | ||
|
|
||
|
|
||
| void TCPWrap::GetTOS(const FunctionCallbackInfo<Value>& args) { | ||
| TCPWrap* wrap; | ||
| ASSIGN_OR_RETURN_UNWRAP( | ||
| &wrap, args.This(), args.GetReturnValue().Set(UV_EBADF)); | ||
|
|
||
| int fd; | ||
| int err = uv_fileno(reinterpret_cast<uv_handle_t*>(&wrap->handle_), &fd); | ||
| if (err != 0) { | ||
| args.GetReturnValue().Set(err); | ||
| return; | ||
| } | ||
|
|
||
| int tos = 0; | ||
| socklen_t len = sizeof(tos); | ||
|
|
||
| #ifdef _WIN32 | ||
| args.GetReturnValue().Set(UV_ENOSYS); | ||
| #else | ||
| // Try IPv4 first | ||
| if (getsockopt(fd, IPPROTO_IP, IP_TOS, &tos, &len) == 0) { | ||
| args.GetReturnValue().Set(tos); | ||
| return; | ||
| } | ||
|
|
||
| // If IPv4 failed, try IPv6 | ||
| if (getsockopt(fd, IPPROTO_IPV6, IPV6_TCLASS, &tos, &len) == 0) { | ||
| args.GetReturnValue().Set(tos); | ||
| return; | ||
| } | ||
|
|
||
| // If both failed, return the negative errno | ||
| args.GetReturnValue().Set(-errno); | ||
ronag marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| #endif | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wouldn't say this needs to block this PR, but upstreaming these additions to https://github.com/libuv/libuv might be a good follow-up change
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. even i was thinking the same, if internal members of nodejs will work and do the changes over there to libuv, then additions will be fast, rather than i do.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you can open an issue there pointing to this PR, that will help and maybe someone picks it up.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @santigimeno i already made an issue there, and a member of libuv is working on that, untill that, we could make a todo here in the cpp code to track the isssue and its relevant pr, and will update the libuv api, once it is rolled out. i looked a long on recent issues, prs whch got merged and i saw that it took a lot of time, but as we need to roll out this feature soon in the next minor version, we could consider forward looking at this pr so that we could easily bring the feature |
||
| } | ||
|
|
||
|
|
||
| #ifdef _WIN32 | ||
| void TCPWrap::SetSimultaneousAccepts(const FunctionCallbackInfo<Value>& args) { | ||
| TCPWrap* wrap; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,59 @@ | ||
| 'use strict'; | ||
| const common = require('../common'); | ||
| const assert = require('assert'); | ||
| const net = require('net'); | ||
|
|
||
| // 1. Check if the platform supports TOS | ||
| // Your implementation returns UV_ENOSYS on Windows, so we expect an error there. | ||
amyssnippet marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| const isWindows = common.isWindows; | ||
|
|
||
| const server = net.createServer(common.mustCall((socket) => { | ||
| socket.end(); | ||
| })); | ||
|
|
||
| server.listen(0, common.mustCall(() => { | ||
| const port = server.address().port; | ||
| const client = net.connect(port); | ||
|
|
||
| client.on('connect', common.mustCall(() => { | ||
| // TEST 1: setTOS validation | ||
| // Should throw if value is not a number or out of range | ||
| assert.throws(() => client.setTOS('invalid'), { | ||
| code: 'ERR_INVALID_ARG_TYPE' | ||
| }); | ||
| assert.throws(() => client.setTOS(NaN), { | ||
| code: 'ERR_INVALID_ARG_TYPE' | ||
| }); | ||
| assert.throws(() => client.setTOS(256), { | ||
| code: 'ERR_OUT_OF_RANGE' | ||
| }); | ||
| assert.throws(() => client.setTOS(-1), { | ||
| code: 'ERR_OUT_OF_RANGE' | ||
| }); | ||
|
|
||
| // TEST 2: setting and getting TOS | ||
| const tosValue = 0x10; // IPTOS_LOWDELAY (16) | ||
|
|
||
| if (isWindows) { | ||
| // On Windows, your implementation returns UV_ENOSYS, which throws in JS | ||
| assert.throws(() => client.setTOS(tosValue), { | ||
| code: 'ENOSYS' | ||
| }); | ||
| } else { | ||
| // On POSIX (Linux/macOS), this should succeed | ||
| client.setTOS(tosValue); | ||
|
|
||
| // Verify values | ||
| // Note: Some OSs might mask the value (e.g. Linux sometimes masks ECN bits), | ||
| // but usually 0x10 should return 0x10. | ||
| const got = client.getTOS(); | ||
| assert.strictEqual(got, tosValue, `Expected TOS ${tosValue}, got ${got}`); | ||
| } | ||
|
|
||
| client.end(); | ||
| })); | ||
|
|
||
| client.on('end', () => { | ||
amyssnippet marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| server.close(); | ||
| }); | ||
| })); | ||
Uh oh!
There was an error while loading. Please reload this page.