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

Client connections sending SIGPIPE #34

Closed
stonier opened this issue Feb 4, 2014 · 2 comments
Closed

Client connections sending SIGPIPE #34

stonier opened this issue Feb 4, 2014 · 2 comments
Assignees
Milestone

Comments

@stonier
Copy link
Owner

stonier commented Feb 4, 2014

@jakan2 says that the ecl socket server is getting killed when the client connection breaks. The relevant ecl code:

long SocketServer::write(const char *s, unsigned long n) ecl_debug_throw_decl(StandardException) {
    int bytes_written = ::send(client_socket_fd,s,n,0);
    if ( bytes_written < 0 ) {
        switch(errno) {
            case ( EPIPE ) : {
                close();
                return ConnectionHungUp;
            }
            default : {
                ecl_debug_throw( devices::send_exception(LOC) );
                error_handler = devices::send_error();
                return ConnectionProblem;
            }
        }
    }
}

So it seems we already had handling for exactly this in our old use cases, but this no longer works. Look up the man pages:

   EPIPE  The  local  end  has been shut down on a connection oriented socket.  In this case the process will also receive a SIGPIPE unless MSG_NOSIGNAL is set.

So SIGPIPE is getting sent which kills the server. The 'fix' would be to do this:

  int bytes_written = ::send(client_socket_fd,s,n,0);
  int bytes_written = ::send(client_socket_fd,s,n,MSG_NOSIGNAL);

The question is....why is this code falling over now and not before? If we know this, then we can know that we're not introducing another problem.

@ghost ghost assigned stonier Feb 4, 2014
@stonier
Copy link
Owner Author

stonier commented Feb 4, 2014

@jakan2 - I think I found the reason. From the man pages:

POSIX.1-2001 only describes the MSG_OOB and MSG_EOR flags.  POSIX.1-2008 adds a specification of MSG_NOSIGNAL.

Probably the linux operating systems we were using did not have POSIX.1-2008 implementations.

@stonier
Copy link
Owner Author

stonier commented Feb 4, 2014

We should handle cases where the signal is not defined - I updated the server code appropriately.

#ifdef MSG_NOSIGNAL
    int bytes_written = ::send(client_socket_fd,s,n,0|MSG_NOSIGNAL);
#else
    int bytes_written = ::send(client_socket_fd,s,n,0);
#endif

@stonier stonier closed this as completed Feb 4, 2014
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

1 participant