curl / Mailing Lists / curl-library / Single Mail

curl-library

unexpected code 35 (if tcp listen backlog is full)

From: Michael Kilburn via curl-library <curl-library_at_cool.haxx.se>
Date: Sat, 13 Jan 2018 03:16:16 -0600

Hi,

Environment:
CentOS 7
libcurl 7.54 compiled with OpenSSL

I am observing strange behavior -- when server's TCP backlog is overflowing
I naturally start getting curl code 7. But I also get curl code 35 and (as
time goes by) they become more and more prevalent (after 1-2 hours). It
looks like a bug to me -- I shouldn't get anything TLS-specific until TCP
connection is established. Sufficiently increasing server's TCP backlog
size makes both problems to go away. Is it normal?

Client app has ~30-60 threads each performing more or less the same
operation in a loop (with some delay in-between):
     curl_easy_init()
     configure handle to send a POST request to https endpoint
     curl_easy_perform()
     curl_easy_cleanup() -- I know it is inefficient

Code for server (it is a mockup), if your certificate has private key in
the same file -- keyfile param is not required:

#!/usr/bin/python
import time
import BaseHTTPServer
import urlparse
import ssl

HOST_NAME = '<hostname>' # !!!REMEMBER TO CHANGE THIS!!!
PORT_NUMBER = 9000 # Maybe set this to 9000.

class MyHandler(BaseHTTPServer.BaseHTTPRequestHandler):
    def do_HEAD(s):
        s.send_response(200)
        s.send_header("Content-type", "text/html")
        s.end_headers()
    def do_GET(s):
        """Respond to a GET request."""
        s.send_response(200)
        s.send_header("Content-type", "text/html")
        s.end_headers()
        s.wfile.write("<html><head><title>Title goes here.</title></head>")
        s.wfile.write("<body><p>This is a test.</p>")
        # If someone went to "http://something.somewhere.net/foo/bar/",
        # then s.path equals "/foo/bar/".
        s.wfile.write("<p>You accessed path: %s</p>" % s.path)
        s.wfile.write("</body></html>")
    def do_POST(s):
        """Respond to a POST request."""
        # Handle Expect: header
        if s.headers.get('Expect') == '100-continue':
            s.send_response(100)
            s.end_headers()

        # Extract and print the contents of the POST
        length = int(s.headers['Content-Length'])
        post_data = urlparse.parse_qs(s.rfile.read(length).decode('utf-8'))
        for key, value in post_data.iteritems():
            print "%s=%s" % (key, value)

        print s.headers

        s.send_response(201)
        s.send_header("Content-Length", 0) # WinSSL demands this
        s.end_headers()

class MyServer(BaseHTTPServer.HTTPServer):
    def server_activate(self):
        self.socket.listen(128) # set it to 5 to reproduce

if __name__ == '__main__':
    httpd = MyServer((HOST_NAME, PORT_NUMBER), MyHandler)

    httpd.socket = ssl.wrap_socket (httpd.socket, certfile='./server.pem',
keyfile='./private.key', server_side=True)
    print time.asctime(), "Server Starts - %s:%s" % (HOST_NAME, PORT_NUMBER)
    try:
        httpd.serve_forever()
    except KeyboardInterrupt:
        pass
    httpd.server_close()
    print time.asctime(), "Server Stops - %s:%s" % (HOST_NAME, PORT_NUMBER)

-- 
Regards,
Michael.

-------------------------------------------------------------------
Unsubscribe: https://cool.haxx.se/list/listinfo/curl-library
Etiquette: https://curl.haxx.se/mail/etiquette.html
Received on 2018-01-13