| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent f8805c4 commit e365814
6 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -227,6 +227,20 @@ never have reason to call this. | |||
| 227 | 227 | If `multicastInterface` is not specified, the operating system will attempt to | |
| 228 | 228 | drop membership on all valid interfaces. | |
| 229 | 229 | ||
| 230 | + ### socket.getRecvBufferSize(size) | ||
| 231 | + <!-- YAML | ||
| 232 | + added: REPLACEME | ||
| 233 | + --> | ||
| 234 | + | ||
| 235 | + * Returns {number} the `SO_RCVBUF` socket receive buffer size in bytes. | ||
| 236 | + | ||
| 237 | + ### socket.getSendBufferSize(size) | ||
| 238 | + <!-- YAML | ||
| 239 | + added: REPLACEME | ||
| 240 | + --> | ||
| 241 | + | ||
| 242 | + * Returns {number} the `SO_SNDBUF` socket send buffer size in bytes. | ||
| 243 | + | ||
| 230 | 244 | ### socket.ref() | |
| 231 | 245 | <!-- YAML | |
| 232 | 246 | added: v0.9.1 | |
@@ -476,6 +490,26 @@ decremented to 0 by a router, it will not be forwarded. | |||
| 476 | 490 | The argument passed to to `socket.setMulticastTTL()` is a number of hops | |
| 477 | 491 | between 0 and 255. The default on most systems is `1` but can vary. | |
| 478 | 492 | ||
| 493 | + ### socket.setRecvBufferSize(size) | ||
| 494 | + <!-- YAML | ||
| 495 | + added: REPLACEME | ||
| 496 | + --> | ||
| 497 | + | ||
| 498 | + * `size` {number} Integer | ||
| 499 | + | ||
| 500 | + Sets the `SO_RCVBUF` socket option. Sets the maximum socket receive buffer | ||
| 501 | + in bytes. | ||
| 502 | + | ||
| 503 | + ### socket.setSendBufferSize(size) | ||
| 504 | + <!-- YAML | ||
| 505 | + added: REPLACEME | ||
| 506 | + --> | ||
| 507 | + | ||
| 508 | + * `size` {number} Integer | ||
| 509 | + | ||
| 510 | + Sets the `SO_SNDBUF` socket option. Sets the maximum socket send buffer | ||
| 511 | + in bytes. | ||
| 512 | + | ||
| 479 | 513 | ### socket.setTTL(ttl) | |
| 480 | 514 | <!-- YAML | |
| 481 | 515 | added: v0.1.101 | |
@@ -539,6 +573,9 @@ changes: | |||
| 539 | 573 | - version: v8.6.0 | |
| 540 | 574 | pr-url: https://github.com/nodejs/node/pull/14560 | |
| 541 | 575 | description: The `lookup` option is supported. | |
| 576 | + - version: REPLACEME | ||
| 577 | + pr-url: https://github.com/nodejs/node/pull/13623 | ||
| 578 | + description: `recvBufferSize` and `sendBufferSize` options are supported now. | ||
| 542 | 579 | --> | |
| 543 | 580 | ||
| 544 | 581 | * `options` {Object} Available options are: | |
@@ -547,6 +584,8 @@ changes: | |||
| 547 | 584 | * `reuseAddr` {boolean} When `true` [`socket.bind()`][] will reuse the | |
| 548 | 585 | address, even if another process has already bound a socket on it. Optional. | |
| 549 | 586 | Defaults to `false`. | |
| 587 | + * `recvBufferSize` {number} - Optional. Sets the `SO_RCVBUF` socket value. | ||
| 588 | + * `sendBufferSize` {number} - Optional. Sets the `SO_SNDBUF` socket value. | ||
| 550 | 589 | * `lookup` {Function} Custom lookup function. Defaults to [`dns.lookup()`][]. | |
| 551 | 590 | Optional. | |
| 552 | 591 | * `callback` {Function} Attached as a listener for `'message'` events. Optional. | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -98,15 +98,19 @@ function _createSocketHandle(address, port, addressType, fd, flags) { | |||
| 98 | 98 | return handle; | |
| 99 | 99 | } | |
| 100 | 100 | ||
| 101 | + const kOptionSymbol = Symbol('options symbol'); | ||
| 101 | 102 | ||
| 102 | 103 | function Socket(type, listener) { | |
| 103 | 104 | EventEmitter.call(this); | |
| 104 | 105 | var lookup; | |
| 105 | 106 | ||
| 107 | + this[kOptionSymbol] = {}; | ||
| 106 | 108 | if (type !== null && typeof type === 'object') { | |
| 107 | 109 | var options = type; | |
| 108 | 110 | type = options.type; | |
| 109 | 111 | lookup = options.lookup; | |
| 112 | + this[kOptionSymbol].recvBufferSize = options.recvBufferSize; | ||
| 113 | + this[kOptionSymbol].sendBufferSize = options.sendBufferSize; | ||
| 110 | 114 | } | |
| 111 | 115 | ||
| 112 | 116 | var handle = newHandle(type, lookup); | |
@@ -141,6 +145,12 @@ function startListening(socket) { | |||
| 141 | 145 | socket._bindState = BIND_STATE_BOUND; | |
| 142 | 146 | socket.fd = -42; // compatibility hack | |
| 143 | 147 | ||
| 148 | + if (socket[kOptionSymbol].recvBufferSize) | ||
| 149 | + bufferSize(socket, socket[kOptionSymbol].recvBufferSize, 'recv'); | ||
| 150 | + | ||
| 151 | + if (socket[kOptionSymbol].sendBufferSize) | ||
| 152 | + bufferSize(socket, socket[kOptionSymbol].sendBufferSize, 'send'); | ||
| 153 | + | ||
| 144 | 154 | socket.emit('listening'); | |
| 145 | 155 | } | |
| 146 | 156 | ||
@@ -157,6 +167,20 @@ function replaceHandle(self, newHandle) { | |||
| 157 | 167 | self._handle = newHandle; | |
| 158 | 168 | } | |
| 159 | 169 | ||
| 170 | + function bufferSize(self, size, buffer) { | ||
| 171 | + if (size >>> 0 !== size) | ||
| 172 | + throw new errors.TypeError('ERR_SOCKET_BAD_BUFFER_SIZE'); | ||
| 173 | + | ||
| 174 | + try { | ||
| 175 | + if (buffer === 'recv') | ||
| 176 | + return self._handle.bufferSize(size, 0); | ||
| 177 | + else | ||
| 178 | + return self._handle.bufferSize(size, 1); | ||
| 179 | + } catch (e) { | ||
| 180 | + throw new errors.Error('ERR_SOCKET_BUFFER_SIZE', e); | ||
| 181 | + } | ||
| 182 | + } | ||
| 183 | + | ||
| 160 | 184 | Socket.prototype.bind = function(port_, address_ /*, callback*/) { | |
| 161 | 185 | let port = port_; | |
| 162 | 186 | ||
@@ -651,6 +675,27 @@ Socket.prototype.unref = function() { | |||
| 651 | 675 | return this; | |
| 652 | 676 | }; | |
| 653 | 677 | ||
| 678 | + | ||
| 679 | + Socket.prototype.setRecvBufferSize = function(size) { | ||
| 680 | + bufferSize(this, size, 'recv'); | ||
| 681 | + }; | ||
| 682 | + | ||
| 683 | + | ||
| 684 | + Socket.prototype.setSendBufferSize = function(size) { | ||
| 685 | + bufferSize(this, size, 'send'); | ||
| 686 | + }; | ||
| 687 | + | ||
| 688 | + | ||
| 689 | + Socket.prototype.getRecvBufferSize = function() { | ||
| 690 | + return bufferSize(this, 0, 'recv'); | ||
| 691 | + }; | ||
| 692 | + | ||
| 693 | + | ||
| 694 | + Socket.prototype.getSendBufferSize = function() { | ||
| 695 | + return bufferSize(this, 0, 'send'); | ||
| 696 | + }; | ||
| 697 | + | ||
| 698 | + | ||
| 654 | 699 | module.exports = { | |
| 655 | 700 | _createSocketHandle, | |
| 656 | 701 | createSocket, | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -46,6 +46,7 @@ using v8::Object; | |||
| 46 | 46 | using v8::PropertyAttribute; | |
| 47 | 47 | using v8::PropertyCallbackInfo; | |
| 48 | 48 | using v8::String; | |
| 49 | + using v8::Uint32; | ||
| 49 | 50 | using v8::Undefined; | |
| 50 | 51 | using v8::Value; | |
| 51 | 52 | ||
@@ -135,6 +136,7 @@ void UDPWrap::Initialize(Local<Object> target, | |||
| 135 | 136 | env->SetProtoMethod(t, "setMulticastLoopback", SetMulticastLoopback); | |
| 136 | 137 | env->SetProtoMethod(t, "setBroadcast", SetBroadcast); | |
| 137 | 138 | env->SetProtoMethod(t, "setTTL", SetTTL); | |
| 139 | + env->SetProtoMethod(t, "bufferSize", BufferSize); | ||
| 138 | 140 | ||
| 139 | 141 | env->SetProtoMethod(t, "ref", HandleWrap::Ref); | |
| 140 | 142 | env->SetProtoMethod(t, "unref", HandleWrap::Unref); | |
@@ -223,6 +225,43 @@ void UDPWrap::Bind6(const FunctionCallbackInfo<Value>& args) { | |||
| 223 | 225 | } | |
| 224 | 226 | ||
| 225 | 227 | ||
| 228 | + void UDPWrap::BufferSize(const FunctionCallbackInfo<Value>& args) { | ||
| 229 | + Environment* env = Environment::GetCurrent(args); | ||
| 230 | + UDPWrap* wrap; | ||
| 231 | + ASSIGN_OR_RETURN_UNWRAP(&wrap, | ||
| 232 | + args.Holder(), | ||
| 233 | + args.GetReturnValue().Set(UV_EBADF)); | ||
| 234 | + | ||
| 235 | + CHECK(args[0]->IsUint32()); | ||
| 236 | + CHECK(args[1]->IsUint32()); | ||
| 237 | + int size = static_cast<int>(args[0].As<Uint32>()->Value()); | ||
| 238 | + | ||
| 239 | + if (size != args[0].As<Uint32>()->Value()) { | ||
| 240 | + if (args[1].As<Uint32>()->Value() == 0) | ||
| 241 | + return env->ThrowUVException(EINVAL, "uv_recv_buffer_size"); | ||
| 242 | + else | ||
| 243 | + return env->ThrowUVException(EINVAL, "uv_send_buffer_size"); | ||
| 244 | + } | ||
| 245 | + | ||
| 246 | + int err; | ||
| 247 | + if (args[1].As<Uint32>()->Value() == 0) { | ||
| 248 | + err = uv_recv_buffer_size(reinterpret_cast<uv_handle_t*>(&wrap->handle_), | ||
| 249 | + &size); | ||
| 250 | + } else { | ||
| 251 | + err = uv_send_buffer_size(reinterpret_cast<uv_handle_t*>(&wrap->handle_), | ||
| 252 | + &size); | ||
| 253 | + } | ||
| 254 | + | ||
| 255 | + if (err != 0) { | ||
| 256 | + if (args[1].As<Uint32>()->Value() == 0) | ||
| 257 | + return env->ThrowUVException(err, "uv_recv_buffer_size"); | ||
| 258 | + else | ||
| 259 | + return env->ThrowUVException(err, "uv_send_buffer_size"); | ||
| 260 | + } | ||
| 261 | + args.GetReturnValue().Set(size); | ||
| 262 | + } | ||
| 263 | + | ||
| 264 | + | ||
| 226 | 265 | #define X(name, fn) \ | |
| 227 | 266 | void UDPWrap::name(const FunctionCallbackInfo<Value>& args) { \ | |
| 228 | 267 | UDPWrap* wrap = Unwrap<UDPWrap>(args.Holder()); \ | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -57,6 +57,7 @@ class UDPWrap: public HandleWrap { | |||
| 57 | 57 | const v8::FunctionCallbackInfo<v8::Value>& args); | |
| 58 | 58 | static void SetBroadcast(const v8::FunctionCallbackInfo<v8::Value>& args); | |
| 59 | 59 | static void SetTTL(const v8::FunctionCallbackInfo<v8::Value>& args); | |
| 60 | + static void BufferSize(const v8::FunctionCallbackInfo<v8::Value>& args); | ||
| 60 | 61 | ||
| 61 | 62 | static v8::Local<v8::Object> Instantiate(Environment* env, AsyncWrap* parent); | |
| 62 | 63 | uv_udp_t* UVHandle(); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -39,3 +39,23 @@ validTypes.forEach((validType) => { | |||
| 39 | 39 | socket.close(); | |
| 40 | 40 | }); | |
| 41 | 41 | }); | |
| 42 | + | ||
| 43 | + // Ensure buffer sizes can be set | ||
| 44 | + { | ||
| 45 | + const socket = dgram.createSocket({ | ||
| 46 | + type: 'udp4', | ||
| 47 | + recvBufferSize: 10000, | ||
| 48 | + sendBufferSize: 15000 | ||
| 49 | + }); | ||
| 50 | + | ||
| 51 | + socket.bind(common.mustCall(() => { | ||
| 52 | + // note: linux will double the buffer size | ||
| 53 | + assert.ok(socket.getRecvBufferSize() === 10000 || | ||
| 54 | + socket.getRecvBufferSize() === 20000, | ||
| 55 | + 'SO_RCVBUF not 1300 or 2600'); | ||
| 56 | + assert.ok(socket.getSendBufferSize() === 15000 || | ||
| 57 | + socket.getSendBufferSize() === 30000, | ||
| 58 | + 'SO_SNDBUF not 1800 or 3600'); | ||
| 59 | + socket.close(); | ||
| 60 | + })); | ||
| 61 | + } | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,74 @@ | |||
| 1 | + 'use strict'; | ||
| 2 | + | ||
| 3 | + const common = require('../common'); | ||
| 4 | + const assert = require('assert'); | ||
| 5 | + const dgram = require('dgram'); | ||
| 6 | + | ||
| 7 | + { | ||
| 8 | + // Should throw error if the socket is never bound. | ||
| 9 | + const errorObj = { | ||
| 10 | + code: 'ERR_SOCKET_BUFFER_SIZE', | ||
| 11 | + type: Error, | ||
| 12 | + message: /^Could not get or set buffer size:.*$/ | ||
| 13 | + }; | ||
| 14 | + | ||
| 15 | + const socket = dgram.createSocket('udp4'); | ||
| 16 | + | ||
| 17 | + assert.throws(() => { | ||
| 18 | + socket.setRecvBufferSize(8192); | ||
| 19 | + }, common.expectsError(errorObj)); | ||
| 20 | + | ||
| 21 | + assert.throws(() => { | ||
| 22 | + socket.setSendBufferSize(8192); | ||
| 23 | + }, common.expectsError(errorObj)); | ||
| 24 | + | ||
| 25 | + assert.throws(() => { | ||
| 26 | + socket.getRecvBufferSize(); | ||
| 27 | + }, common.expectsError(errorObj)); | ||
| 28 | + | ||
| 29 | + assert.throws(() => { | ||
| 30 | + socket.getSendBufferSize(); | ||
| 31 | + }, common.expectsError(errorObj)); | ||
| 32 | + } | ||
| 33 | + | ||
| 34 | + { | ||
| 35 | + // Should throw error if invalid buffer size is specified | ||
| 36 | + const errorObj = { | ||
| 37 | + code: 'ERR_SOCKET_BAD_BUFFER_SIZE', | ||
| 38 | + type: TypeError, | ||
| 39 | + message: /^Buffer size must be a positive integer$/ | ||
| 40 | + }; | ||
| 41 | + | ||
| 42 | + const badBufferSizes = [-1, Infinity, 'Doh!']; | ||
| 43 | + | ||
| 44 | + const socket = dgram.createSocket('udp4'); | ||
| 45 | + | ||
| 46 | + socket.bind(common.mustCall(() => { | ||
| 47 | + badBufferSizes.forEach((badBufferSize) => { | ||
| 48 | + assert.throws(() => { | ||
| 49 | + socket.setRecvBufferSize(badBufferSize); | ||
| 50 | + }, common.expectsError(errorObj)); | ||
| 51 | + | ||
| 52 | + assert.throws(() => { | ||
| 53 | + socket.setSendBufferSize(badBufferSize); | ||
| 54 | + }, common.expectsError(errorObj)); | ||
| 55 | + }); | ||
| 56 | + socket.close(); | ||
| 57 | + })); | ||
| 58 | + } | ||
| 59 | + | ||
| 60 | + { | ||
| 61 | + // Can set and get buffer sizes after binding the socket. | ||
| 62 | + const socket = dgram.createSocket('udp4'); | ||
| 63 | + | ||
| 64 | + socket.bind(common.mustCall(() => { | ||
| 65 | + socket.setRecvBufferSize(10000); | ||
| 66 | + socket.setSendBufferSize(10000); | ||
| 67 | + | ||
| 68 | + // note: linux will double the buffer size | ||
| 69 | + const expectedBufferSize = common.isLinux ? 20000 : 10000; | ||
| 70 | + assert.strictEqual(socket.getRecvBufferSize(), expectedBufferSize); | ||
| 71 | + assert.strictEqual(socket.getSendBufferSize(), expectedBufferSize); | ||
| 72 | + socket.close(); | ||
| 73 | + })); | ||
| 74 | + } | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments