Skip to content
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

Socket::SOMAXCONN() on Solaris #8980

Open
p5pRT opened this issue Jul 30, 2007 · 9 comments
Open

Socket::SOMAXCONN() on Solaris #8980

p5pRT opened this issue Jul 30, 2007 · 9 comments

Comments

@p5pRT
Copy link

p5pRT commented Jul 30, 2007

Migrated from rt.perl.org#44259 (status was 'open')

Searchable as RT44259$

@p5pRT
Copy link
Author

p5pRT commented Jul 30, 2007

From @schweikert

Created by @schweikert

This is a bug report for perl from david@​schweikert.ch,
generated with the help of perlbug 1.35 running under perl v5.8.8.

-----------------------------------------------------------------
Socket​::SOMAXCONN() on Solaris always returns 5, which is also the value that
can be found in sys/socket.h. In reality, Solaris supports more than 5 as
backlog argument to listen() and SOMAXCONN is defined as 5 for historical
reasons (I presume). The real value can be tuned at runtime and queried with
the following command​:

$ ndd /dev/tcp tcp_conn_req_max_q

The consequence of the fact that Socket​::SOMAXCONN() always returns 5 on
Solaris is that applications which want the highest possible value of backlog
for listen(), might call Socket​::SOMAXCONN() to find out what that value is and
end up using a pretty low value for it. Net​::Server does so for example.

I propose to do one of the following​:

- Find out the real value at run-time when Socket​::SOMAXCONN() is called. I
  don't know however if there is an efficient method to do this (i.e. without
  calling ndd)

- Return a higher fixed value on Solaris. I think that a minimum like 128 should
  be available everywhere. The default is 1024...

Thanks and Cheers
David Schweikert

Perl Info

Flags:
    category=library
    severity=medium

Site configuration information for perl v5.8.8:

Configured by root at Thu Jun 14 19:28:09 MEST 2007.

Summary of my perl5 (revision 5 version 8 subversion 8) configuration:
  Platform:
    osname=solaris, osvers=2.8, archname=sun4-solaris
    uname='sunos turbine 5.8 generic_117000-05 sun4u sparc sunw,sun-fire-v240 '
    config_args='-ds -e -Dprefix=/opt/perl -Dotherlibdirs=/opt/perlm/lib:/opt/ssl/cpan/lib:/opt/bdb/cpan/lib:/opt/pgsql/cpan/lib:/opt/apach/cpan/lib:/opt/apch2/cpan/lib -Dnoextensions=DB_File -Dpager=/usr/bin/less -isR'
    hint=recommended, useposix=true, d_sigaction=define
    usethreads=undef use5005threads=undef useithreads=undef usemultiplicity=undef
    useperlio=define d_sfio=undef uselargefiles=define usesocks=undef
    use64bitint=undef use64bitall=undef uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='cc', ccflags ='-fno-strict-aliasing -pipe -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
    optimize='-O',
    cppflags='-fno-strict-aliasing -pipe -I/usr/local/include'
    ccversion='', gccversion='3.2.3', gccosandvers='solaris2.8'
    intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=4321
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16
    ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
    alignbytes=8, prototype=define
  Linker and Libraries:
    ld='cc', ldflags =' -L/usr/local/lib '
    libpth=/usr/local/lib /usr/lib /usr/ccs/lib
    libs=-lsocket -lnsl -ldb -ldl -lm -lc
    perllibs=-lsocket -lnsl -ldl -lm -lc
    libc=/lib/libc.so, so=so, useshrplib=false, libperl=libperl.a
    gnulibc_version=''
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags=' '
    cccdlflags='-fPIC', lddlflags='-G -L/usr/local/lib'

Locally applied patches:
    


@INC for perl v5.8.8:
    /opt/perl/lib/5.8.8/sun4-solaris
    /opt/perl/lib/5.8.8
    /opt/perl/lib/site_perl/5.8.8/sun4-solaris
    /opt/perl/lib/site_perl/5.8.8
    /opt/perl/lib/site_perl
    /opt/perlm/lib/sun4-solaris
    /opt/perlm/lib
    /opt/ssl/cpan/lib/5.8.8/sun4-solaris
    /opt/ssl/cpan/lib/5.8.8
    /opt/ssl/cpan/lib
    /opt/bdb/cpan/lib/5.8.8/sun4-solaris
    /opt/bdb/cpan/lib/5.8.8
    /opt/bdb/cpan/lib
    /opt/pgsql/cpan/lib/5.8.8/sun4-solaris
    /opt/pgsql/cpan/lib/5.8.8
    /opt/pgsql/cpan/lib
    /opt/apach/cpan/lib/5.8.8/sun4-solaris
    /opt/apach/cpan/lib/5.8.8
    /opt/apach/cpan/lib
    /opt/apch2/cpan/lib
    .


Environment for perl v5.8.8:
    HOME=/net/users/dws
    LANG (unset)
    LANGUAGE (unset)
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=/net/users/dws/bin:/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:/usr/openwin/bin:/usr/ccs/bin:/usr/ucb:/opt/base/bin
    PERL_BADLANG (unset)
    SHELL=/bin/bash

@p5pRT
Copy link
Author

p5pRT commented Jul 30, 2007

From @nwc10

On Mon, Jul 30, 2007 at 06​:09​:12AM -0700, David Schweikert wrote​:

Socket​::SOMAXCONN() on Solaris always returns 5, which is also the value that
can be found in sys/socket.h. In reality, Solaris supports more than 5 as
backlog argument to listen() and SOMAXCONN is defined as 5 for historical
reasons (I presume). The real value can be tuned at runtime and queried with
the following command​:

$ ndd /dev/tcp tcp_conn_req_max_q

How does Solaris document that a C program should query this value?
By running that command via popen() and parsing the result? Or a more direct
way?

Nicholas Clark

@p5pRT
Copy link
Author

p5pRT commented Jul 30, 2007

The RT System itself - Status changed from 'new' to 'open'

@p5pRT
Copy link
Author

p5pRT commented Jul 30, 2007

From @smpeters

On Mon, Jul 30, 2007 at 07​:00​:57PM +0100, Nicholas Clark wrote​:

On Mon, Jul 30, 2007 at 06​:09​:12AM -0700, David Schweikert wrote​:

Socket​::SOMAXCONN() on Solaris always returns 5, which is also the value that
can be found in sys/socket.h. In reality, Solaris supports more than 5 as
backlog argument to listen() and SOMAXCONN is defined as 5 for historical
reasons (I presume). The real value can be tuned at runtime and queried with
the following command​:

$ ndd /dev/tcp tcp_conn_req_max_q

How does Solaris document that a C program should query this value?
By running that command via popen() and parsing the result? Or a more direct
way?

This is very old, but seems very relevant...

  http​://www.usenix.org/publications/perl/perl15.html

  On almost every socket implementation in existence, the maximum queue length
  that you can set is 5 (so handle incoming connection requests quickly!), and
  SOMAXCONN (another helpful constant from Socket.pm) is usually set to 5. If
  you try to set the queue length to a value above 5, the operating system
  silently throttles the queue length back to the maximum value. Solaris 2.x
  is the only modern operating system that I am aware of where you can
  meaningfully specify queue length values that are greater than 5 (though
  interestingly SOMAXCONN is still given as 5 in the Solaris 2.x system
  header files).

Steve Peters
steve@​fisharerojo.org

@p5pRT
Copy link
Author

p5pRT commented Jul 31, 2007

From @schweikert

On Mon, Jul 30, 2007 at 11​:23​:26 -0700, Nicholas Clark via RT wrote​:

How does Solaris document that a C program should query this value?
By running that command via popen() and parsing the result? Or a more
direct
way?

It is not documented and I don't think that it can be done without
calling ndd :-(

However, in the "Solaris Tunable Parameters Reference Manual" it is
written that the default for that parameter is 128. It can be changed,
but most likely to increase it, so it should be safe to assume that it
is everywhere at least 128.

I was courious to see if the "tcp_conn_req_max_q" was also relevant to
Unix domain sockets and had a look at the OpenSolaris source code. It
isn't​: the maximum queue size for Unix domain sockets is fixed and
defined to be 4096 (in OpenSolaris, not sure about other Solaris
versions). The parameter is called TL_MAXQLEN and I have found it here​:
/usr/src/uts/common/io/tl.c

I have also seen in the source code that the backlog parameter is
automatically adjusted to the maximum value if you give a value that is
too large (for both unix and inet sockets). So it really
shouldn't be a problem just returning 128 or even somethink higher.

Cheers
David

@p5pRT
Copy link
Author

p5pRT commented Jul 31, 2007

From @doughera88

On Mon, 30 Jul 2007, Nicholas Clark wrote​:

On Mon, Jul 30, 2007 at 06​:09​:12AM -0700, David Schweikert wrote​:

Socket​::SOMAXCONN() on Solaris always returns 5, which is also the value that
can be found in sys/socket.h. In reality, Solaris supports more than 5 as
backlog argument to listen() and SOMAXCONN is defined as 5 for historical
reasons (I presume). The real value can be tuned at runtime and queried with
the following command​:

$ ndd /dev/tcp tcp_conn_req_max_q

How does Solaris document that a C program should query this value?

They don't, as far as I've been able to tell.

By running that command via popen() and parsing the result? Or a more direct
way?

Apparently. The query simply returns a single number, so very
little parsing is needed.

  $ /usr/sbin/ndd /dev/tcp tcp_conn_req_max_q
  128

The NOTES section from the Solaris 8 man pages has the following caveats​:

  The parameters supported by each driver may change from
  release to release. Like programs that read /dev/kmem, user
  programs or shell scripts that execute ndd should be
  prepared for parameter names to change.

  The ioctl() command that ndd uses to communicate with
  drivers is likely to change in a future release. User pro-
  grams should avoid making dependencies on it.

  The meanings of many ndd parameters make sense only if you
  understand how the driver is implemented.

but this one, at least, appears to have been stable since somewhere
around Solaris 7, so it's probably ok to try it. (It's in /usr/sbin on
my machine, which isn't in a normal user's PATH.)

--
  Andy Dougherty doughera@​lafayette.edu

@p5pRT
Copy link
Author

p5pRT commented Jul 31, 2007

From @schweikert

On Tue, Jul 31, 2007 at 06​:25​:49 -0700, Andy Dougherty via RT wrote​:

How does Solaris document that a C program should query this value?
...
By running that command via popen() and parsing the result? Or a
more direct way?

Apparently. The query simply returns a single number, so very
little parsing is needed.

$ /usr/sbin/ndd /dev/tcp tcp\_conn\_req\_max\_q
128

Note however that this value is only pertinent for TCP sockets and not
for Unix domain sockets (like I said in my previous comment to this
ticket).

Cheers
David

@p5pRT
Copy link
Author

p5pRT commented Jul 31, 2007

From @schweikert

On Mon, Jul 30, 2007 at 11​:23​:26 -0700, Nicholas Clark via RT wrote​:

How does Solaris document that a C program should query this value?
By running that command via popen() and parsing the result? Or a more direct
way?

It is not documented and I don't think that it can be done without
calling ndd :-(

However, in the "Solaris Tunable Parameters Reference Manual" it is
written that the default for that parameter is 128. It can be changed,
but most likely to increase it, so it should be safe to assume that it
is everywhere at least 128.

I was courious to see if the "tcp_conn_req_max_q" was also relevant to
Unix domain sockets and had a look at the OpenSolaris source code. It
isn't​: the maximum queue size for Unix domain sockets is fixed and
defined to be 4096 (in OpenSolaris, not sure about other Solaris
versions). The parameter is called TL_MAXQLEN and I have found it here​:
/usr/src/uts/common/io/tl.c

I have also seen in the source code that the backlog parameter is
automatically adjusted to the maximum value if you give a value that is
too large (for both unix and inet sockets). So it really
shouldn't be a problem just returning 128 or even somethink higher.

Cheers
David

@p5pRT
Copy link
Author

p5pRT commented Jul 31, 2007

From @schweikert

On Tue, Jul 31, 2007 at 06​:25​:49 -0700, Andy Dougherty via RT wrote​:

How does Solaris document that a C program should query this value?
...
By running that command via popen() and parsing the result? Or a more direct
way?

Apparently. The query simply returns a single number, so very
little parsing is needed.

$ /usr/sbin/ndd /dev/tcp tcp\_conn\_req\_max\_q
128

Note however that this value is only pertinent for TCP sockets and not
for Unix domain sockets (like I said in a previous comment to this
ticket).

Cheers
David

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants