@@ -54,13 +54,15 @@ const {
5454 normalizedArgsSymbol,
5555 makeSyncWrite,
5656} = require ( 'internal/net' ) ;
57+
5758const assert = require ( 'internal/assert' ) ;
5859const {
5960 UV_EADDRINUSE ,
6061 UV_EINVAL ,
6162 UV_ENOTCONN ,
6263 UV_ECANCELED ,
6364 UV_ETIMEDOUT ,
65+ UV_EBADF ,
6466} = internalBinding ( 'uv' ) ;
6567const { convertIpv6StringToBuffer } = internalBinding ( 'cares_wrap' ) ;
6668
@@ -474,7 +476,15 @@ function Socket(options) {
474476 this [ kSetNoDelay ] = Boolean ( options . noDelay ) ;
475477 this [ kSetKeepAlive ] = Boolean ( options . keepAlive ) ;
476478 this [ kSetKeepAliveInitialDelay ] = ~ ~ ( options . keepAliveInitialDelay / 1000 ) ;
477- this [ kSetTOS ] = options . TOS ;
479+ // Optional initial TOS hint (0 - 255)
480+ if ( options . tos !== undefined ) {
481+ validateNumber ( options . tos , 'options.tos' ) ;
482+ if ( ! Number . isInteger ( options . tos ) || options . tos < 0 || options . tos > 255 )
483+ throw new ERR_INVALID_ARG_VALUE ( 'options.tos' , options . tos ) ;
484+ this [ kSetTOS ] = options . tos ;
485+ } else {
486+ this [ kSetTOS ] = undefined ;
487+ }
478488
479489 // Shut down the socket when we're finished with it.
480490 this . on ( 'end' , onReadableStreamEnd ) ;
@@ -487,6 +497,10 @@ function Socket(options) {
487497 // If we have a handle, then start the flow of data into the
488498 // buffer. if not, then this will happen when we connect
489499 if ( this . _handle && options . readable !== false ) {
500+ // Apply pending TOS if present and supported by the handle
501+ if ( this [ kSetTOS ] !== undefined && this . _handle . setTOS )
502+ this . _handle . setTOS ( this [ kSetTOS ] ) ;
503+
490504 if ( options . pauseOnCreate ) {
491505 // Stop the handle from reading and pause the stream
492506 this . _handle . reading = false ;
@@ -655,43 +669,38 @@ Socket.prototype.setKeepAlive = function(enable, initialDelayMsecs) {
655669
656670
657671Socket . prototype . setTOS = function ( tos ) {
658- if ( NumberIsNaN ( tos ) ) {
659- throw new ERR_INVALID_ARG_TYPE ( 'tos' , 'number' , tos ) ;
672+ validateNumber ( tos , 'tos' ) ;
673+
674+ // TOS must be an integer in the range 0..255.
675+ if ( ! Number . isInteger ( tos ) || tos < 0 || tos > 255 ) {
676+ throw new ErrnoException ( UV_EINVAL , 'setTOS' ) ;
660677 }
661- validateInt32 ( tos , 'tos' , 0 , 255 ) ;
662678
663679 if ( ! this . _handle ) {
664680 this [ kSetTOS ] = tos ;
665681 return this ;
666682 }
667683
668- if ( this . _handle . setTOS && tos !== this [ kSetTOS ] ) {
684+ if ( ! this . _handle . setTOS ) {
685+ // Handle doesn't support TOS; no-op and remember value
669686 this [ kSetTOS ] = tos ;
670- const err = this . _handle . setTOS ( tos ) ;
671- if ( err ) {
672- throw new ErrnoException ( err , 'setTOS' ) ;
673- }
687+ return this ;
674688 }
675689
690+ const err = this . _handle . setTOS ( tos ) ;
691+ // Ignore EBADF: transient fd-not-ready states are possible; defer to
692+ // after connect when the fd is guaranteed to be ready.
693+ if ( err && err !== UV_EBADF ) throw new ErrnoException ( err , 'setTOS' ) ;
694+ this [ kSetTOS ] = tos ;
676695 return this ;
677696} ;
678697
679-
680698Socket . prototype . getTOS = function ( ) {
681- if ( ! this . _handle ) {
682- // Return cached value if set, otherwise default to 0
683- return this [ kSetTOS ] !== undefined ? this [ kSetTOS ] : 0 ;
684- }
685-
686- if ( ! this . _handle . getTOS ) {
687- return this [ kSetTOS ] ;
688- }
689-
690- const res = this . _handle . getTOS ( ) ;
691- if ( typeof res === 'number' && res < 0 ) {
692- throw new ErrnoException ( res , 'getTOS' ) ;
693- }
694- return res ;
699+ if ( ! this . _handle ) throw new ERR_SOCKET_CLOSED ( ) ;
700+ if ( ! this . _handle . getTOS ) return undefined ;
701+ const r = this . _handle . getTOS ( ) ;
702+ if ( r < 0 ) throw new ErrnoException ( r , 'getTOS' ) ;
703+ return r ;
695704} ;
696705
697706
@@ -1663,7 +1672,12 @@ function afterConnect(status, handle, req, readable, writable) {
16631672 }
16641673
16651674 if ( self [ kSetTOS ] !== undefined && self . _handle . setTOS ) {
1666- self . _handle . setTOS ( self [ kSetTOS ] ) ;
1675+ const err = self . _handle . setTOS ( self [ kSetTOS ] ) ;
1676+ if ( err && err !== UV_EBADF ) {
1677+ // Non-fatal: surface as an 'error' event to avoid throwing during
1678+ // connect callbacks
1679+ self . emit ( 'error' , new ErrnoException ( err , 'setTOS' ) ) ;
1680+ }
16671681 }
16681682
16691683 self . emit ( 'connect' ) ;
0 commit comments