| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 3ad4d9b commit 4cf94fa
5 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -747,6 +747,9 @@ it to interact with the client. | |||
| 747 | 747 | <!-- YAML | |
| 748 | 748 | added: v0.3.4 | |
| 749 | 749 | changes: | |
| 750 | + - version: REPLACEME | ||
| 751 | + pr-url: https://github.com/nodejs/node/pull/61503 | ||
| 752 | + description: Added `typeOfService` option. | ||
| 750 | 753 | - version: v15.14.0 | |
| 751 | 754 | pr-url: https://github.com/nodejs/node/pull/37735 | |
| 752 | 755 | description: AbortSignal support was added. | |
@@ -788,6 +791,7 @@ changes: | |||
| 788 | 791 | otherwise ignored. **Default:** `false`. | |
| 789 | 792 | * `signal` {AbortSignal} An Abort signal that may be used to destroy the | |
| 790 | 793 | socket. | |
| 794 | + * `typeOfService` {number} The initial Type of Service (TOS) value. | ||
| 791 | 795 | * `writable` {boolean} Allow writes on the socket when an `fd` is passed, | |
| 792 | 796 | otherwise ignored. **Default:** `false`. | |
| 793 | 797 | * Returns: {net.Socket} | |
@@ -1461,6 +1465,45 @@ If `timeout` is 0, then the existing idle timeout is disabled. | |||
| 1461 | 1465 | The optional `callback` parameter will be added as a one-time listener for the | |
| 1462 | 1466 | [`'timeout'`][] event. | |
| 1463 | 1467 | ||
| 1468 | + ### `socket.getTypeOfService()` | ||
| 1469 | + | ||
| 1470 | + <!-- YAML | ||
| 1471 | + added: REPLACEME | ||
| 1472 | + --> | ||
| 1473 | + | ||
| 1474 | + * Returns: {integer} The current TOS value. | ||
| 1475 | + | ||
| 1476 | + Returns the current Type of Service (TOS) field for IPv4 packets or Traffic | ||
| 1477 | + Class for IPv6 packets for this socket. | ||
| 1478 | + | ||
| 1479 | + `setTypeOfService()` may be called before the socket is connected; the value | ||
| 1480 | + will be cached and applied when the socket establishes a connection. | ||
| 1481 | + `getTypeOfService()` will return the currently set value even before connection. | ||
| 1482 | + | ||
| 1483 | + On some platforms (e.g., Linux), certain TOS/ECN bits may be masked or ignored, | ||
| 1484 | + and behavior can differ between IPv4 and IPv6 or dual-stack sockets. Callers | ||
| 1485 | + should verify platform-specific semantics. | ||
| 1486 | + | ||
| 1487 | + ### `socket.setTypeOfService(tos)` | ||
| 1488 | + | ||
| 1489 | + <!-- YAML | ||
| 1490 | + added: REPLACEME | ||
| 1491 | + --> | ||
| 1492 | + | ||
| 1493 | + * `tos` {integer} The TOS value to set (0-255). | ||
| 1494 | + * Returns: {net.Socket} The socket itself. | ||
| 1495 | + | ||
| 1496 | + Sets the Type of Service (TOS) field for IPv4 packets or Traffic Class for IPv6 | ||
| 1497 | + Packets sent from this socket. This can be used to prioritize network traffic. | ||
| 1498 | + | ||
| 1499 | + `setTypeOfService()` may be called before the socket is connected; the value | ||
| 1500 | + will be cached and applied when the socket establishes a connection. | ||
| 1501 | + `getTypeOfService()` will return the currently set value even before connection. | ||
| 1502 | + | ||
| 1503 | + On some platforms (e.g., Linux), certain TOS/ECN bits may be masked or ignored, | ||
| 1504 | + and behavior can differ between IPv4 and IPv6 or dual-stack sockets. Callers | ||
| 1505 | + should verify platform-specific semantics. | ||
| 1506 | + | ||
| 1464 | 1507 | ### `socket.timeout` | |
| 1465 | 1508 | ||
| 1466 | 1509 | <!-- YAML | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -57,6 +57,7 @@ const { | |||
| 57 | 57 | const assert = require('internal/assert'); | |
| 58 | 58 | const { | |
| 59 | 59 | UV_EADDRINUSE, | |
| 60 | + UV_EBADF, | ||
| 60 | 61 | UV_EINVAL, | |
| 61 | 62 | UV_ENOTCONN, | |
| 62 | 63 | UV_ECANCELED, | |
@@ -358,6 +359,7 @@ const kBytesWritten = Symbol('kBytesWritten'); | |||
| 358 | 359 | const kSetNoDelay = Symbol('kSetNoDelay'); | |
| 359 | 360 | const kSetKeepAlive = Symbol('kSetKeepAlive'); | |
| 360 | 361 | const kSetKeepAliveInitialDelay = Symbol('kSetKeepAliveInitialDelay'); | |
| 362 | + const kSetTOS = Symbol('kSetTOS'); | ||
| 361 | 363 | ||
| 362 | 364 | function Socket(options) { | |
| 363 | 365 | if (!(this instanceof Socket)) return new Socket(options); | |
@@ -473,6 +475,10 @@ function Socket(options) { | |||
| 473 | 475 | this[kSetNoDelay] = Boolean(options.noDelay); | |
| 474 | 476 | this[kSetKeepAlive] = Boolean(options.keepAlive); | |
| 475 | 477 | this[kSetKeepAliveInitialDelay] = ~~(options.keepAliveInitialDelay / 1000); | |
| 478 | + if (options.typeOfService !== undefined) { | ||
| 479 | + validateInt32(options.typeOfService, 'options.typeOfService', 0, 255); | ||
| 480 | + } | ||
| 481 | + this[kSetTOS] = options.typeOfService; | ||
| 476 | 482 | ||
| 477 | 483 | // Shut down the socket when we're finished with it. | |
| 478 | 484 | this.on('end', onReadableStreamEnd); | |
@@ -652,6 +658,59 @@ Socket.prototype.setKeepAlive = function(enable, initialDelayMsecs) { | |||
| 652 | 658 | }; | |
| 653 | 659 | ||
| 654 | 660 | ||
| 661 | + Socket.prototype.setTypeOfService = function(tos) { | ||
| 662 | + if (NumberIsNaN(tos)) { | ||
| 663 | + throw new ERR_INVALID_ARG_TYPE('tos', 'number', tos); | ||
| 664 | + } | ||
| 665 | + validateInt32(tos, 'tos', 0, 255); | ||
| 666 | + | ||
| 667 | + if (!this._handle) { | ||
| 668 | + this[kSetTOS] = tos; | ||
| 669 | + return this; | ||
| 670 | + } | ||
| 671 | + | ||
| 672 | + if (!this._handle.setTypeOfService) { | ||
| 673 | + this[kSetTOS] = tos; | ||
| 674 | + return this; | ||
| 675 | + } | ||
| 676 | + | ||
| 677 | + if (tos !== this[kSetTOS]) { | ||
| 678 | + this[kSetTOS] = tos; | ||
| 679 | + const err = this._handle.setTypeOfService(tos); | ||
| 680 | + // On Windows, setting TOS is often restricted or returns error codes even if partially applied. | ||
| 681 | + // We treat this as a "best effort" operation and do not throw on Windows. | ||
| 682 | + if (err && !isWindows) { | ||
| 683 | + throw new ErrnoException(err, 'setTypeOfService'); | ||
| 684 | + } | ||
| 685 | + } | ||
| 686 | + | ||
| 687 | + return this; | ||
| 688 | + }; | ||
| 689 | + | ||
| 690 | + | ||
| 691 | + Socket.prototype.getTypeOfService = function() { | ||
| 692 | + if (!this._handle) { | ||
| 693 | + // Return cached value if set, otherwise default to 0 | ||
| 694 | + return this[kSetTOS] !== undefined ? this[kSetTOS] : 0; | ||
| 695 | + } | ||
| 696 | + | ||
| 697 | + if (!this._handle.getTypeOfService) { | ||
| 698 | + return this[kSetTOS] !== undefined ? this[kSetTOS] : 0; | ||
| 699 | + } | ||
| 700 | + | ||
| 701 | + const res = this._handle.getTypeOfService(); | ||
| 702 | + if (typeof res === 'number' && res < 0) { | ||
| 703 | + // On Windows, getsockopt(IP_TOS) often fails. In that case, fall back | ||
| 704 | + // to the cached value we attempted to set, or 0. | ||
| 705 | + if (isWindows) { | ||
| 706 | + return this[kSetTOS] !== undefined ? this[kSetTOS] : 0; | ||
| 707 | + } | ||
| 708 | + throw new ErrnoException(res, 'getTypeOfService'); | ||
| 709 | + } | ||
| 710 | + return res; | ||
| 711 | + }; | ||
| 712 | + | ||
| 713 | + | ||
| 655 | 714 | Socket.prototype.address = function() { | |
| 656 | 715 | return this._getsockname(); | |
| 657 | 716 | }; | |
@@ -1619,6 +1678,15 @@ function afterConnect(status, handle, req, readable, writable) { | |||
| 1619 | 1678 | self._handle.setKeepAlive(true, self[kSetKeepAliveInitialDelay]); | |
| 1620 | 1679 | } | |
| 1621 | 1680 | ||
| 1681 | + if (self[kSetTOS] !== undefined && self._handle.setTypeOfService) { | ||
| 1682 | + const err = self._handle.setTypeOfService(self[kSetTOS]); | ||
| 1683 | + // On Windows, setting TOS is best-effort. If it fails, we shouldn't destroy | ||
| 1684 | + // the connection or emit an error, as the socket is otherwise healthy. | ||
| 1685 | + if (err && err !== UV_EBADF && !isWindows) { | ||
| 1686 | + self.emit('error', new ErrnoException(err, 'setTypeOfService')); | ||
| 1687 | + } | ||
| 1688 | + } | ||
| 1689 | + | ||
| 1622 | 1690 | self.emit('connect'); | |
| 1623 | 1691 | self.emit('ready'); | |
| 1624 | 1692 | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments