httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Dean Gaudet <dgau...@arctic.org>
Subject Re: more solaris stuff
Date Mon, 28 Jul 1997 18:25:18 GMT


On Mon, 28 Jul 1997, Marc Slemko wrote:

> On Mon, 28 Jul 1997, Dean Gaudet wrote:
> 
> > Ok, the test program below does essentially what apache does with the hup
> > patch.  That is:  socket, bind, dup. 
> 
> No.  You are missing the critical step of accepting connections.

Ya know, I realised this last night a little too late.  I never tested any
of this with an accepted connection.  Boy was I being silly, solaris
sucks.  FWIW the SO_REUSEADDR probably isn't important either.  I copied
all of the make_sock stuff into my test program... and the only thing I
don't have is an accept().  And when I add it, it fails spectacularly on
my system. 

It not only fails to rebind the next time around, I cannot even bind to
that port if I run the program again.  Test program included below. 
Solaris is supremely lame. 

We should never dup a socket under solaris.  Even with SIGUSR1 it's a
problem as soon as the httpd exits.  I just verified this. 

My suggestion is to disable the slack call entirely for sockets for
solaris < 260. 

I'll work up a patch and revamp the known_problems page. 

Dean

#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <signal.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <netinet/tcp.h>

void other_stuff (int t)
{
    int one;
    struct linger li;
    int bufsiz;

    one = 1;
    if (setsockopt(t, SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(int)) < 0) {
	perror ("SO_REUSEADDR");
	exit (1);
    }
    one = 1;
    if (setsockopt(t, SOL_SOCKET,SO_KEEPALIVE,(char *)&one,sizeof(int)) < 0) {
	perror ("SO_KEEPALIVE");
	exit (1);
    }
    one = 1;
    if (setsockopt(t, IPPROTO_TCP,TCP_NODELAY,(char *)&one,sizeof(int)) < 0) {
	perror ("TCP_NODELAY");
	exit (1);
    }
    li.l_onoff = 1;
    li.l_linger = 30;
    if (setsockopt(t, SOL_SOCKET,SO_LINGER,(char *)&li,sizeof(li)) < 0) {
	perror ("SO_LINGER");
	exit (1);
    }
    bufsiz = 16384;
    if (setsockopt(t, SOL_SOCKET, SO_SNDBUF,(char *)&bufsiz,sizeof(bufsiz))<0) {
	perror ("SO_SNDBUF");
	exit (1);
    }
    if (listen (t, 512) == -1) {
	perror ("listen");
	exit (1);
    }
}

void main (void)
{
    int i, s, t;
    struct sockaddr_in sa;
    struct sockaddr sa_client;
    int clen;

    sa.sin_family = AF_INET;
    sa.sin_addr.s_addr = htonl (INADDR_ANY);
    sa.sin_port = htons (2719);

    for (i = 0; i < 20; ++i) {
        printf ("i = %d\n", i);
	if ((s = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {
	    perror ("socket");
	    exit (1);
	}
	if (bind (s, (struct sockaddr *)&sa, sizeof (sa)) == -1) {
	    fprintf (stderr, "i = %d, bind: %s\n", i, strerror (errno));
	    exit (1);
	}
	if ((t = fcntl (s, F_DUPFD, 255)) == -1) {
	    perror ("dup");
	    exit (1);
	}
	close (s);
	other_stuff (t);
        clen = sizeof (sa_client);
	s = accept (t, &sa_client, &clen);
	if (s < 0) {
	    perror ("accept");
	} else {
	    close (s);
	}
	close (t);
	sleep (20);
    }
    exit (0);
}



Mime
View raw message