Changeset 4572

Show
Ignore:
Timestamp:
02/17/10 14:12:07 (5 months ago)
Author:
phk
Message:

Try to handle socket state calls that return errno's relating
to the client absconding the TCP connection.

This comes to the fore on Solaris, where not only systemcalls which
push data through sockets (read,write,select...) return these errors,
but also socket-state calls (setsockopt, ioctl, fcntl) do.

Root cause of trouble in #626 & al.

Location:
trunk/varnish-cache
Files:
3 modified

Legend:

Unmodified
Added
Removed
  • trunk/varnish-cache/bin/varnishd/cache_acceptor.c

    r4565 r4572  
    106106        struct timeval tv; 
    107107        socklen_t l; 
     108        int i; 
    108109 
    109110        l = sizeof lin; 
    110         AZ(getsockopt(fd, SOL_SOCKET, SO_LINGER, &lin, &l)); 
     111        i = getsockopt(fd, SOL_SOCKET, SO_LINGER, &lin, &l); 
     112        if (i) { 
     113                TCP_Assert(i); 
     114                return; 
     115        } 
    111116        assert(l == sizeof lin); 
    112117        if (memcmp(&lin, &linger, l)) 
     
    115120#ifdef SO_SNDTIMEO_WORKS 
    116121        l = sizeof tv; 
    117         AZ(getsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, &l)); 
     122        i = getsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, &l); 
     123        if (i) { 
     124                TCP_Assert(i); 
     125                return; 
     126        } 
    118127        assert(l == sizeof tv); 
    119128        if (memcmp(&tv, &tv_sndtimeo, l)) 
     
    127136#ifdef SO_RCVTIMEO_WORKS 
    128137        l = sizeof tv; 
    129         AZ(getsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, &l)); 
     138        i = getsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, &l); 
     139        if (i) { 
     140                TCP_Assert(i); 
     141                return; 
     142        } 
    130143        assert(l == sizeof tv); 
    131144        if (memcmp(&tv, &tv_rcvtimeo, l)) 
     
    169182                sock_test(sp->fd); 
    170183        if (need_linger) 
    171                 AZ(setsockopt(sp->fd, SOL_SOCKET, SO_LINGER, 
     184                TCP_Assert(setsockopt(sp->fd, SOL_SOCKET, SO_LINGER, 
    172185                    &linger, sizeof linger)); 
    173186#ifdef SO_SNDTIMEO_WORKS 
    174187        if (need_sndtimeo) 
    175                 AZ(setsockopt(sp->fd, SOL_SOCKET, SO_SNDTIMEO, 
     188                TCP_Assert(setsockopt(sp->fd, SOL_SOCKET, SO_SNDTIMEO, 
    176189                    &tv_sndtimeo, sizeof tv_sndtimeo)); 
    177190#endif 
    178191#ifdef SO_RCVTIMEO_WORKS 
    179192        if (need_rcvtimeo) 
    180                 AZ(setsockopt(sp->fd, SOL_SOCKET, SO_RCVTIMEO, 
     193                TCP_Assert(setsockopt(sp->fd, SOL_SOCKET, SO_RCVTIMEO, 
    181194                    &tv_rcvtimeo, sizeof tv_rcvtimeo)); 
    182195#endif 
     
    366379         * acceptor thread, to reduce syscall density of the latter. 
    367380         */ 
    368         TCP_nonblocking(sp->fd); 
    369         if (vca_act->pass == NULL) 
     381        if (TCP_nonblocking(sp->fd)) 
     382                vca_close_session(sp, "remote closed"); 
     383        else if (vca_act->pass == NULL) 
    370384                assert(sizeof sp == write(vca_pipes[1], &sp, sizeof sp)); 
    371385        else 
  • trunk/varnish-cache/include/libvarnish.h

    r4458 r4572  
    6161#define TCP_PORTBUFSIZE         16 
    6262 
     63#define TCP_Check(a) ((a) == 0 || errno == ECONNRESET || errno == ENOTCONN) 
     64 
     65#define TCP_Assert(a) assert(TCP_Check(a)) 
     66 
    6367void TCP_myname(int sock, char *abuf, unsigned alen, char *pbuf, unsigned plen); 
    6468void TCP_hisname(int sock, char *abuf, unsigned alen, char *pbuf, unsigned plen); 
    6569int TCP_filter_http(int sock); 
    66 void TCP_blocking(int sock); 
    67 void TCP_nonblocking(int sock); 
    68 void TCP_linger(int sock, int linger); 
     70int TCP_blocking(int sock); 
     71int TCP_nonblocking(int sock); 
     72int TCP_linger(int sock, int linger); 
    6973#ifdef SOL_SOCKET 
    7074void TCP_name(const struct sockaddr *addr, unsigned l, char *abuf, 
  • trunk/varnish-cache/lib/libvarnish/tcp.c

    r4567 r4572  
    155155 */ 
    156156 
    157 void 
     157int 
    158158TCP_blocking(int sock) 
    159159{ 
    160         int i; 
     160        int i, j; 
    161161 
    162162        i = 0; 
    163         AZ(ioctl(sock, FIONBIO, &i)); 
    164 } 
    165  
    166 void 
     163        j = ioctl(sock, FIONBIO, &i); 
     164        TCP_Assert(j); 
     165        return (j); 
     166} 
     167 
     168int 
    167169TCP_nonblocking(int sock) 
    168170{ 
    169         int i; 
     171        int i, j; 
    170172 
    171173        i = 1; 
    172         AZ(ioctl(sock, FIONBIO, &i)); 
     174        j = ioctl(sock, FIONBIO, &i); 
     175        TCP_Assert(j); 
     176        return (j); 
    173177} 
    174178 
     
    256260 */ 
    257261 
    258 void 
     262int 
    259263TCP_linger(int sock, int linger) 
    260264{ 
     
    265269        lin.l_onoff = linger; 
    266270        i = setsockopt(sock, SOL_SOCKET, SO_LINGER, &lin, sizeof lin); 
    267         assert(i == 0 || errno == EBADF); 
    268 } 
     271        TCP_Assert(i); 
     272        return (i); 
     273}