Poštni seznam arhiviranih sporo?il

Od: "Steven Levine" <ecs-isp@2rosenthals.com> Glava
Izvorno E-sporo?ilo
Zadeva: Re: [eCS-ISP] socket - no buffer space availble
Datum: Tue, 29 Jul 2025 16:25:42 -0700
Za: "eCS ISP Mailing List" <ecs-isp@2rosenthals.com>

In <list-13712173@2rosenthals.com>, on 07/29/25
   at 07:45 PM, "Massimo S." <ecs-isp@2rosenthals.com> said:

Hi Massimo,

>>       0 STREAM           42164        http..80 217.182.195.225  FIN_WAIT_2
>>       0 STREAM           56842      https..443    103.42.4.140  FIN_WAIT_2
>>       0 STREAM           18331        http..80   51.68.111.239  FIN_WAIT_2
>>       0 STREAM           62505        http..80  91.225.160.193  FIN_WAIT_2

>FIN_WAIT_2 has no universally mandated timeout in TCP protocol, so some
>OSes keep these sockets indefinitely  without cleanup.

This may have been true at one time.  However, all the examples I'm seem
imply that the current default timeout is 60 seconds.  Also, looking that
the FreeBSD 3.2 sources which are very close to the code used to port the
stack we use, I'm pretty sure can see where the timeout is set to 2 times
the Maximum Segment Lifetime which would be 2 minutes on a system with the
default settings.

>I add, that i've seen that even closing apache the hundreds of sockets
>stay in FIN_WAIT_2 and do not disappear

How long did you wait?  I would not be surprised if the timeout was 2
minutes.

You can try the attached and see if it can deal with the sockets stuck in
FIN_WAIT_2.  It's basically a manual version of socktidy.  Run it as
CloseSocket and give it a list of sockets to close.

I've never tested it against FIN_WAIT_2 sockets, so it might have no
ettect.

Steven

--
----------------------------------------------------------------------
"Steven Levine" <steve53@earthlink.net>  Warp/DIY/BlueLion etc.
www.scoug.com www.arcanoae.com www.warpcave.com
----------------------------------------------------------------------
/* CloseSocket - close socket

   Copyright (c) 2002-2017 Steven Levine and Associates, Inc.
   All rights reserved.

   2001-06-14 SHL - Release
   2014-06-12 SHL Sync with templates
   2016-10-19 SHL Sync with templates
   2017-11-30 SHL Correct typo
   2017-11-30 SHL Convert to Globals style
   2017-11-30 SHL Sync with templates
*/

signal on Error
signal on Failure name Error
signal on Halt
signal on NotReady name Error
signal on NoValue name Error
signal on Syntax name Error

gVersion = '0.1';

Globals = 'gArgList. gCmdName gDbgLvl gErrCondition gSock. gVersion'

call Initialize

Main:

  /* Load socket functions */
  call RxFuncAdd 'SockLoadFuncs','rxSock','SockLoadFuncs'

  call SockLoadFuncs 0

  parse arg cmdLine
  call ScanArgs cmdLine
  drop cmdLine

  do iArg = 1 to gArgList.0
    gSock.!Socket = gArgList.iArg
    call DoClose
  end

  exit 0

/* end main */

/*=== DoClose() Close socket ===*/

DoClose: procedure expose (Globals)
  say 'Closing socket' gSock.!Socket
  call SockCloseX
  return 0

/* end DoClose */

/*=== Initialize() Initialize globals ===*/

Initialize:
  call LoadRexxUtil
  call GetCmdName
  call SockLoadRxSock
  return

/* end Initialize */

/*=== ScanArgsInit() ScanArgs initialization exit routine ===*/

ScanArgsInit: procedure expose (Globals) cmdTail swCtl keepQuoted
  /* Preset defaults */
  gDbgLvl = 0
  gArgList.0 = 0 /* Reset arg count */
  return

/* end ScanArgsInit */

/*=== ScanArgsSwitch() ScanArgs switch option exit routine ===*/

ScanArgsSwitch: procedure expose (Globals) curSw curSwArg
  select
  when curSw == 'h' | curSw == '?' then
    call ScanArgsHelp
  when curSw == 'V' then do
    say gCmdName gVersion
    exit
  end
  otherwise
    call ScanArgsUsage 'switch '''curSw''' unexpected'
  end /* select */

  return

/* end ScanArgsSwitch */

/*=== ScanArgsArg() ScanArgs argument option exit routine ===*/

ScanArgsArg: procedure expose (Globals) curArg
  i = gArgList.0 + 1
  gArgList.i = curArg
  gArgList.0 = i
  return

/* end ScanArgsArg */

/*=== ScanArgsTerm() ScanArgs scan end exit routine ===*/

ScanArgsTerm: procedure expose (Globals)
  if gArgList.0 = 0 then
    call ScanArgsUsage 'required arguments missing'
  return

/* end ScanArgsTerm */

/*=== ScanArgsHelp() Display ScanArgs usage help exit routine ===*/

ScanArgsHelp:
  say
  say 'Try to close selected sockets.'
  say
  say 'Usage:' gCmdName '[-h] [-V] [-?] socket...'
  say
  say '  -h -?        Display this message'
  say '  -V           Display version number and quit'
  say
  say '  socket       Socket to close'
  exit 255

/* end ScanArgsHelp */

/*=== ScanArgsUsage(message) Report Scanargs usage error exit routine ===*/

ScanArgsUsage:
  parse arg msg
  say
  if msg \== '' then
    say msg
  say 'Usage:' gCmdName '[-h] [-V] [-?] socket...'
  exit 255

/* end ScanArgsUsage */

/*==============================================================================*/
/*=== SkelRexxFunc standards - Delete unused - Move modified above this mark ===*/
/*==============================================================================*/

/*=== DbgMsg([level, ]message,...) Write multi-line message to STDERR if debugging ===*/

DbgMsg: procedure expose (Globals)
  level = arg(1)
  if datatype(level, 'W') then
    start = 2
  else do
    level = 1
    start = 1
  end
  if level <= gDbgLvl then do
    do i = start to arg()
      msg = arg(i)
      if msg \== '' then
msg = ' *' msg
      call lineout 'STDERR', msg
    end
  end
  return

/* end DbgMsg */

/*=== SockCloseX() SockClose wrapper ===*/

SockCloseX: procedure expose (Globals)
  call DbgMsg 2, 'SockCloseX: closing' gSock.!Socket
  gSock.!rc = SockClose(gSock.!Socket)
  s = gSock.!Socket
  drop gSock.!Socket /* Drop now to avoid recursion */
  if gSock.!rc < 0 then
    call SockError 'Close' s
  return

/* end SockCloseX */

/*=== SockDump() Dump gSock. stem content ===*/

SockDump: procedure expose gSock. SIGL

  crlf = '0d0a'x
  s = '' || crlf || ' * Dumping gSock.'

  if symbol('SIGL') == 'VAR' then
    s = s 'at line' SIGL

  s = s 'on' date() time('L') || crlf

  s2 = s

  if symbol('gSock.!HostName') == 'VAR' then
    s = s || ' * HostName:' gSock.!HostName || crlf

  if symbol('gSock.!Socket') == 'VAR' then
    s = s || ' * Socket:' gSock.!Socket || crlf
  if symbol('gSock.!ListenSocket') == 'VAR' then
    s = s || ' * ListenSocket:' gSock.!ListenSocket || crlf

  if symbol('gSock.!Host.!name') == 'VAR' then
    s = s || ' * Host.!name:' gSock.!Host.!name || crlf
  if symbol('gSock.!Host.!port') == 'VAR' then
    s = s || ' * Host.!port:' gSock.!Host.!port || crlf
  if symbol('gSock.!Host.!family') == 'VAR' then
    s = s || ' * Host.!family:' gSock.!Host.!family || crlf
  if symbol('gSock.!Host.!addr') == 'VAR' then
    s = s || ' * Host.!addr:' gSock.!Host.!addr || crlf

  /* If have useful data, show it */
  if s \== s2 then
    call lineout 'STDERR', s

  return

/* end SockDump */

/*=== SockError(request) Report socket error and shutdown or return ===*/

/* Action depends on gSock.!ErrorAction setting
   ABORT - errors are reported, sockets are closed and script exits
   REPORT - errors are reported and the function returns to the caller
   IGNORE - errors are not reported the function returns to the caller
   the default action is abort
 */

SockError:

  if symbol('gSock.!ErrorAction') == 'VAR' then
    action = translate(gSock.!ErrorAction)
  else
    action = 'ABORT'

  if action = 'IGNORE' then return

  parse arg req
  if req == '' then
    req = 'Socket request'
  else
    req = 'Sock' || req

  call lineout 'STDERR', ''
  call lineout 'STDERR', gCmdName':' req 'failed at line' SIGL 'on' date() time('L')

  if symbol('gSock.!rc') == 'VAR' then
    call lineout 'STDERR', gCmdName': gSock.!rc:' gSock.!rc 'errno:' errno 'h_errno:' h_errno
  else
    call lineout 'STDERR', gCmdName':' 'errno:' errno 'h_errno:' h_errno

  call SockDump

  if action = 'REPORT' then return

  if action \= 'ABORT' then
    call lineout 'STDERR', ' Action:' action 'unexpected'

  /* Action is abort */
  if symbol('gSock.!Socket') == 'VAR' then
    call SockCloseX
  if symbol('gSock.!ListenSocket') == 'VAR' then
    call SockCloseListen

  call beep 200, 300

  exit 253

/* end SockError */

/*=== SockLoadRxSock() Load RxSock functions ===*/

SockLoadRxSock:
  if RxFuncQuery('SockLoadFuncs') then do
    call RxFuncAdd 'SockLoadFuncs', 'RXSOCK', 'SockLoadFuncs'
    if RESULT then
      call Die 'Cannot load SockLoadFuncs'
    call SockLoadFuncs 0
  end
  return

/* end SockLoadRxSock */

/*==========================================================================*/
/*=== SkelRexx standards - Delete unused - Move modified above this mark ===*/
/*==========================================================================*/

/*=== Error() Set gErrCondition; report to STDOUT; trace and exit or return if called ===*/

Error:
  say
  parse source . . cmd
  gErrCondition = condition('C')
  say gErrCondition 'signaled at line' SIGL 'of' cmd'.'
  if condition('D') \= '' then
    say 'REXX reason =' condition('D')'.'
  if gErrCondition == 'SYNTAX' & symbol('RC') == 'VAR' then
    say 'REXX error =' RC '-' errortext(RC)'.'
  else if symbol('RC') == 'VAR' then
    say 'RC =' RC'.'
  say 'Source =' sourceline(SIGL)

  if condition('I') \== 'CALL' | gErrCondition == 'NOVALUE' | gErrCondition == 'SYNTAX' then do
    trace '?A'
    say 'Enter REXX commands to debug failure.  Press enter to exit script.'
    nop
    if symbol('RC') \== 'VAR' then
      RC = 255
    exit RC
  end

  return

/* end Error */

/*=== Die([message,...]) Write multi-line message to STDERR and die ===*/

Die:
  call lineout 'STDERR', ''
  do i = 1 to arg()
    call lineout 'STDERR', arg(i)
  end
  call lineout 'STDERR', gCmdName 'aborting at script line' SIGL
  call beep 200, 300
  call SysSleep 2
  exit 254

/* end Die */

/*=== GetCmdName() Get short script name and set gCmdName ===*/

GetCmdName: procedure expose (Globals)
  parse source . . cmd
  cmd = filespec('N', cmd) /* Chop path */
  c = lastpos('.', cmd)
  if c > 1 then
    cmd = left(cmd, c - 1) /* Chop extension */
  gCmdName = translate(cmd, xrange('a', 'z'), xrange('A', 'Z')) /* Lowercase */
  return

/* end GetCmdName */

/*=== Halt() Report HALT condition to STDOUT and exit ===*/

Halt:
  say
  parse source . . cmd
  say condition('C') 'signaled at' cmd 'line' SIGL'.'
  say 'Source =' sourceline(SIGL)
  say 'Sleeping for 2 seconds...'
  call SysSleep 2
  exit 253

/* end Halt */

/*=== LoadRexxUtil() Load RexxUtil functions ===*/

LoadRexxUtil:
  if RxFuncQuery('SysLoadFuncs') then do
    call RxFuncAdd 'SysLoadFuncs', 'REXXUTIL', 'SysLoadFuncs'
    if RESULT then
      call Die 'Cannot load SysLoadFuncs'
    call SysLoadFuncs
  end
  return

/* end LoadRexxUtil */

/*=== ScanArgs(cmdLine) Scan command line ===*/

ScanArgs: procedure expose (Globals)

  /* Calls user exits to process arguments and switches */

  parse arg cmdTail
  cmdTail = strip(cmdTail)

  call ScanArgsInit

  /* Ensure optional settings initialized */
  if symbol('SWCTL') \== 'VAR' then
    swCtl = '' /* Switches that take args, append ? if optional */
  if symbol('KEEPQUOTED') \== 'VAR' then
    keepQuoted = 0 /* Set to 1 to keep arguments quoted */

  /* Scan */
  curArg = '' /* Current arg string */
  curSwList = '' /* Current switch list */
  /* curSwArg = '' */ /* Current switch argument, if needed */
  noMoreSw = 0 /* End of switches */

  do while cmdTail \== '' | curArg \== '' | curSwList \== ''

    if curArg == '' then do
      /* Buffer empty, refill */
      qChar = left(cmdTail, 1) /* Remember quote */
      if \ verify(qChar,'''"', 'M') then
parse var cmdTail curArg cmdTail /* Not quoted */
      else do
/* Arg is quoted */
curArg = ''
do forever
 /* Parse dropping quotes */
 parse var cmdTail (qChar)quotedPart(qChar) cmdTail
 curArg = curArg || quotedPart
 /* Check for escaped quote within quoted string (i.e. "" or '') */
 if left(cmdTail, 1) \== qChar then
   leave /* No, done */
 curArg = curArg || qChar /* Append quote */
 if keepQuoted then
   curArg = curArg || qChar /* Append escaped quote */
 parse var cmdTail (qChar) cmdTail
end /* do */
if keepQuoted then
 curArg = qChar || curArg || qChar /* requote */
      end /* if quoted */
    end

    /* If switch buffer empty, refill */
    if curSwList == '' then do
      if left(curArg, 1) == '-' & curArg \== '-' then do
if noMoreSw then
 call ScanArgsUsage 'switch '''curArg''' unexpected'
else if curArg == '--' then
 noMoreSw = 1
else do
 curSwList = substr(curArg, 2) /* Remember switch string */
 curArg = '' /* Mark empty */
 iterate /* Refill arg buffer */
end
parse var cmdTail curArg cmdTail
      end
    end

    /* If switch in progress */
    if curSwList \== '' then do
      curSw = left(curSwList, 1) /* Next switch */
      curSwList = substr(curSwList, 2) /* Drop from pending */
      /* Check switch allows argument, avoid matching ? */
      if pos(curSw, translate(swCtl,,'?')) \= 0 then do
if curSwList \== '' then do
 curSwArg = curSwList /* Use rest of switch string for switch argument */
 curSwList = ''
end
else if curArg \== '' & left(curArg, 1) \== '-' then do
 curSwArg = curArg /* Arg string is switch argument */
 curArg = '' /* Mark arg string empty */
end
else if pos(curSw'?', swCtl) = 0 then
 call ScanArgsUsage 'Switch' curSw 'requires argument'
else
 curSwArg = '' /* Optional arg omitted */
      end

      call ScanArgsSwitch /* Passing curSw and curSwArg */
      drop curSwArg /* Must be used by now */
    end /* if switch */

    /* If arg */
    else if curArg \== '' then do
      noMoreSw = 1
      call ScanArgsArg /* Passing curArg */
      curArg = ''
    end

  end /* while not done */

  call ScanArgsTerm

  return

/* end ScanArgs */

/* The end */


Naro?iti: Poro?ilo (Feed), Izvle?ek (Digest), Indeks.
Odjava
E-pošta za mojstra za sezname