We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Undocumented behaviour of sni kwarg of remote()
In `remote()` 'server_hostname' ssl arg can be set like this:
```python
remote('172.22.0.2', 9090, ssl=True, sni='example.com')
```
This behaviour of `sni` kwarg is undocumented. Currently only behaviour of passing a bool in documented.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `pwnlib/tubes/remote.py`
Content:
```
1 from __future__ import absolute_import
2 from __future__ import division
3 
4 import socket
5 import socks
6 
7 from pwnlib.log import getLogger
8 from pwnlib.timeout import Timeout
9 from pwnlib.tubes.sock import sock
10 
11 log = getLogger(__name__)
12 
13 class remote(sock):
14     r"""Creates a TCP or UDP-connection to a remote host. It supports
15     both IPv4 and IPv6.
16 
17     The returned object supports all the methods from
18     :class:`pwnlib.tubes.sock` and :class:`pwnlib.tubes.tube`.
19 
20     Arguments:
21         host(str): The host to connect to.
22         port(int): The port to connect to.
23         fam: The string "any", "ipv4" or "ipv6" or an integer to pass to :func:`socket.getaddrinfo`.
24         typ: The string "tcp" or "udp" or an integer to pass to :func:`socket.getaddrinfo`.
25         timeout: A positive number, None or the string "default".
26         ssl(bool): Wrap the socket with SSL
27         ssl_context(ssl.SSLContext): Specify SSLContext used to wrap the socket.
28         sni: Set 'server_hostname' in ssl_args based on the host parameter.
29         sock(socket.socket): Socket to inherit, rather than connecting
30         ssl_args(dict): Pass ssl.wrap_socket named arguments in a dictionary.
31 
32     Examples:
33 
34         >>> r = remote('google.com', 443, ssl=True)
35         >>> r.send(b'GET /\r\n\r\n')
36         >>> r.recvn(4)
37         b'HTTP'
38 
39         If a connection cannot be made, an exception is raised.
40 
41         >>> r = remote('127.0.0.1', 1)
42         Traceback (most recent call last):
43         ...
44         PwnlibException: Could not connect to 127.0.0.1 on port 1
45 
46         You can also use :meth:`.remote.fromsocket` to wrap an existing socket.
47 
48         >>> import socket
49         >>> s = socket.socket()
50         >>> s.connect(('google.com', 80))
51         >>> s.send(b'GET /' + b'\r\n'*2)
52         9
53         >>> r = remote.fromsocket(s)
54         >>> r.recvn(4)
55         b'HTTP'
56     """
57 
58     def __init__(self, host, port,
59                  fam = "any", typ = "tcp",
60                  ssl=False, sock=None, ssl_context=None, ssl_args=None, sni=True,
61                  *args, **kwargs):
62         super(remote, self).__init__(*args, **kwargs)
63 
64         # convert port to string for sagemath support
65         self.rport  = str(port)
66         self.rhost  = host
67 
68         if sock:
69             self.family = sock.family
70             self.type   = sock.type
71             self.proto  = sock.proto
72             self.sock   = sock
73 
74         else:
75             typ = self._get_type(typ)
76             fam = self._get_family(fam)
77             try:
78                 self.sock   = self._connect(fam, typ)
79             except socket.gaierror as e:
80                 if e.errno != socket.EAI_NONAME:
81                     raise
82                 self.error('Could not resolve hostname: %r', host)
83         if self.sock:
84             self.settimeout(self.timeout)
85             self.lhost, self.lport = self.sock.getsockname()[:2]
86 
87             if ssl:
88                 # Deferred import to save startup time
89                 import ssl as _ssl
90 
91                 ssl_args = ssl_args or {}
92                 ssl_context = ssl_context or _ssl.SSLContext(_ssl.PROTOCOL_TLSv1_2)
93                 if isinstance(sni, str):
94                     ssl_args["server_hostname"] = sni
95                 elif sni:
96                     ssl_args["server_hostname"] = host
97                 self.sock = ssl_context.wrap_socket(self.sock,**ssl_args)
98 
99     def _connect(self, fam, typ):
100         sock    = None
101         timeout = self.timeout
102 
103         with self.waitfor('Opening connection to %s on port %s' % (self.rhost, self.rport)) as h:
104             for res in socket.getaddrinfo(self.rhost, self.rport, fam, typ, 0, socket.AI_PASSIVE):
105                 self.family, self.type, self.proto, _canonname, sockaddr = res
106 
107                 if self.type not in [socket.SOCK_STREAM, socket.SOCK_DGRAM]:
108                     continue
109 
110                 h.status("Trying %s", sockaddr[0])
111 
112                 sock = socket.socket(self.family, self.type, self.proto)
113 
114                 if timeout is not None and timeout <= 0:
115                     sock.setblocking(0)
116                 else:
117                     sock.setblocking(1)
118                     sock.settimeout(timeout)
119 
120                 try:
121                     sock.connect(sockaddr)
122                     return sock
123                 except socks.ProxyError:
124                     raise
125                 except socket.error:
126                     pass
127             self.error("Could not connect to %s on port %s", self.rhost, self.rport)
128 
129     @classmethod
130     def fromsocket(cls, socket):
131         """
132         Helper method to wrap a standard python socket.socket with the
133         tube APIs.
134 
135         Arguments:
136             socket: Instance of socket.socket
137 
138         Returns:
139             Instance of pwnlib.tubes.remote.remote.
140         """
141         s = socket
142         host, port = s.getpeername()
143         return remote(host, port, fam=s.family, typ=s.type, sock=s)
144 
145 class tcp(remote):
146     __doc__ = remote.__doc__
147     def __init__(self, host, port, *a, **kw):
148         return super(tcp, self).__init__(host, port, typ="tcp", *a, **kw)
149 
150 class udp(remote):
151     __doc__ = remote.__doc__
152     def __init__(self, host, port, *a, **kw):
153         return super(udp, self).__init__(host, port, typ="udp", *a, **kw)
154 
155 class connect(remote):
156     __doc__ = remote.__doc__
157
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/pwnlib/tubes/remote.py b/pwnlib/tubes/remote.py
--- a/pwnlib/tubes/remote.py
+++ b/pwnlib/tubes/remote.py
@@ -23,11 +23,11 @@
         fam: The string "any", "ipv4" or "ipv6" or an integer to pass to :func:`socket.getaddrinfo`.
         typ: The string "tcp" or "udp" or an integer to pass to :func:`socket.getaddrinfo`.
         timeout: A positive number, None or the string "default".
+        sock(:class:`socket.socket`): Socket to inherit, rather than connecting
         ssl(bool): Wrap the socket with SSL
         ssl_context(ssl.SSLContext): Specify SSLContext used to wrap the socket.
-        sni: Set 'server_hostname' in ssl_args based on the host parameter.
-        sock(socket.socket): Socket to inherit, rather than connecting
-        ssl_args(dict): Pass ssl.wrap_socket named arguments in a dictionary.
+        ssl_args(dict): Pass :func:`ssl.wrap_socket` named arguments in a dictionary.
+        sni(str,bool): Set 'server_hostname' in ssl_args. Set to True to set it based on the host argument. Set to False to not provide any value. Default is True.
 
     Examples:
 
@@ -57,7 +57,7 @@
 
     def __init__(self, host, port,
                  fam = "any", typ = "tcp",
-                 ssl=False, sock=None, ssl_context=None, ssl_args=None, sni=True,
+                 sock=None, ssl=False, ssl_context=None, ssl_args=None, sni=True,
                  *args, **kwargs):
         super(remote, self).__init__(*args, **kwargs)

{"golden_diff": "diff --git a/pwnlib/tubes/remote.py b/pwnlib/tubes/remote.py\n--- a/pwnlib/tubes/remote.py\n+++ b/pwnlib/tubes/remote.py\n@@ -23,11 +23,11 @@\n         fam: The string \"any\", \"ipv4\" or \"ipv6\" or an integer to pass to :func:`socket.getaddrinfo`.\n         typ: The string \"tcp\" or \"udp\" or an integer to pass to :func:`socket.getaddrinfo`.\n         timeout: A positive number, None or the string \"default\".\n+        sock(:class:`socket.socket`): Socket to inherit, rather than connecting\n         ssl(bool): Wrap the socket with SSL\n         ssl_context(ssl.SSLContext): Specify SSLContext used to wrap the socket.\n-        sni: Set 'server_hostname' in ssl_args based on the host parameter.\n-        sock(socket.socket): Socket to inherit, rather than connecting\n-        ssl_args(dict): Pass ssl.wrap_socket named arguments in a dictionary.\n+        ssl_args(dict): Pass :func:`ssl.wrap_socket` named arguments in a dictionary.\n+        sni(str,bool): Set 'server_hostname' in ssl_args. Set to True to set it based on the host argument. Set to False to not provide any value. Default is True.\n \n     Examples:\n \n@@ -57,7 +57,7 @@\n \n     def __init__(self, host, port,\n                  fam = \"any\", typ = \"tcp\",\n-                 ssl=False, sock=None, ssl_context=None, ssl_args=None, sni=True,\n+                 sock=None, ssl=False, ssl_context=None, ssl_args=None, sni=True,\n                  *args, **kwargs):\n         super(remote, self).__init__(*args, **kwargs)\n", "issue": "Undocumented behaviour of sni kwarg of remote()\nIn `remote()` 'server_hostname' ssl arg can be set like this:\r\n```python\r\nremote('172.22.0.2', 9090, ssl=True, sni='example.com')\r\n```\r\nThis behaviour of `sni` kwarg is undocumented. Currently only behaviour of passing a bool in documented.\n", "before_files": [{"content": "from __future__ import absolute_import\nfrom __future__ import division\n\nimport socket\nimport socks\n\nfrom pwnlib.log import getLogger\nfrom pwnlib.timeout import Timeout\nfrom pwnlib.tubes.sock import sock\n\nlog = getLogger(__name__)\n\nclass remote(sock):\n    r\"\"\"Creates a TCP or UDP-connection to a remote host. It supports\n    both IPv4 and IPv6.\n\n    The returned object supports all the methods from\n    :class:`pwnlib.tubes.sock` and :class:`pwnlib.tubes.tube`.\n\n    Arguments:\n        host(str): The host to connect to.\n        port(int): The port to connect to.\n        fam: The string \"any\", \"ipv4\" or \"ipv6\" or an integer to pass to :func:`socket.getaddrinfo`.\n        typ: The string \"tcp\" or \"udp\" or an integer to pass to :func:`socket.getaddrinfo`.\n        timeout: A positive number, None or the string \"default\".\n        ssl(bool): Wrap the socket with SSL\n        ssl_context(ssl.SSLContext): Specify SSLContext used to wrap the socket.\n        sni: Set 'server_hostname' in ssl_args based on the host parameter.\n        sock(socket.socket): Socket to inherit, rather than connecting\n        ssl_args(dict): Pass ssl.wrap_socket named arguments in a dictionary.\n\n    Examples:\n\n        >>> r = remote('google.com', 443, ssl=True)\n        >>> r.send(b'GET /\\r\\n\\r\\n')\n        >>> r.recvn(4)\n        b'HTTP'\n\n        If a connection cannot be made, an exception is raised.\n\n        >>> r = remote('127.0.0.1', 1)\n        Traceback (most recent call last):\n        ...\n        PwnlibException: Could not connect to 127.0.0.1 on port 1\n\n        You can also use :meth:`.remote.fromsocket` to wrap an existing socket.\n\n        >>> import socket\n        >>> s = socket.socket()\n        >>> s.connect(('google.com', 80))\n        >>> s.send(b'GET /' + b'\\r\\n'*2)\n        9\n        >>> r = remote.fromsocket(s)\n        >>> r.recvn(4)\n        b'HTTP'\n    \"\"\"\n\n    def __init__(self, host, port,\n                 fam = \"any\", typ = \"tcp\",\n                 ssl=False, sock=None, ssl_context=None, ssl_args=None, sni=True,\n                 *args, **kwargs):\n        super(remote, self).__init__(*args, **kwargs)\n\n        # convert port to string for sagemath support\n        self.rport  = str(port)\n        self.rhost  = host\n\n        if sock:\n            self.family = sock.family\n            self.type   = sock.type\n            self.proto  = sock.proto\n            self.sock   = sock\n\n        else:\n            typ = self._get_type(typ)\n            fam = self._get_family(fam)\n            try:\n                self.sock   = self._connect(fam, typ)\n            except socket.gaierror as e:\n                if e.errno != socket.EAI_NONAME:\n                    raise\n                self.error('Could not resolve hostname: %r', host)\n        if self.sock:\n            self.settimeout(self.timeout)\n            self.lhost, self.lport = self.sock.getsockname()[:2]\n\n            if ssl:\n                # Deferred import to save startup time\n                import ssl as _ssl\n\n                ssl_args = ssl_args or {}\n                ssl_context = ssl_context or _ssl.SSLContext(_ssl.PROTOCOL_TLSv1_2)\n                if isinstance(sni, str):\n                    ssl_args[\"server_hostname\"] = sni\n                elif sni:\n                    ssl_args[\"server_hostname\"] = host\n                self.sock = ssl_context.wrap_socket(self.sock,**ssl_args)\n\n    def _connect(self, fam, typ):\n        sock    = None\n        timeout = self.timeout\n\n        with self.waitfor('Opening connection to %s on port %s' % (self.rhost, self.rport)) as h:\n            for res in socket.getaddrinfo(self.rhost, self.rport, fam, typ, 0, socket.AI_PASSIVE):\n                self.family, self.type, self.proto, _canonname, sockaddr = res\n\n                if self.type not in [socket.SOCK_STREAM, socket.SOCK_DGRAM]:\n                    continue\n\n                h.status(\"Trying %s\", sockaddr[0])\n\n                sock = socket.socket(self.family, self.type, self.proto)\n\n                if timeout is not None and timeout <= 0:\n                    sock.setblocking(0)\n                else:\n                    sock.setblocking(1)\n                    sock.settimeout(timeout)\n\n                try:\n                    sock.connect(sockaddr)\n                    return sock\n                except socks.ProxyError:\n                    raise\n                except socket.error:\n                    pass\n            self.error(\"Could not connect to %s on port %s\", self.rhost, self.rport)\n\n    @classmethod\n    def fromsocket(cls, socket):\n        \"\"\"\n        Helper method to wrap a standard python socket.socket with the\n        tube APIs.\n\n        Arguments:\n            socket: Instance of socket.socket\n\n        Returns:\n            Instance of pwnlib.tubes.remote.remote.\n        \"\"\"\n        s = socket\n        host, port = s.getpeername()\n        return remote(host, port, fam=s.family, typ=s.type, sock=s)\n\nclass tcp(remote):\n    __doc__ = remote.__doc__\n    def __init__(self, host, port, *a, **kw):\n        return super(tcp, self).__init__(host, port, typ=\"tcp\", *a, **kw)\n\nclass udp(remote):\n    __doc__ = remote.__doc__\n    def __init__(self, host, port, *a, **kw):\n        return super(udp, self).__init__(host, port, typ=\"udp\", *a, **kw)\n\nclass connect(remote):\n    __doc__ = remote.__doc__\n", "path": "pwnlib/tubes/remote.py"}], "after_files": [{"content": "from __future__ import absolute_import\nfrom __future__ import division\n\nimport socket\nimport socks\n\nfrom pwnlib.log import getLogger\nfrom pwnlib.timeout import Timeout\nfrom pwnlib.tubes.sock import sock\n\nlog = getLogger(__name__)\n\nclass remote(sock):\n    r\"\"\"Creates a TCP or UDP-connection to a remote host. It supports\n    both IPv4 and IPv6.\n\n    The returned object supports all the methods from\n    :class:`pwnlib.tubes.sock` and :class:`pwnlib.tubes.tube`.\n\n    Arguments:\n        host(str): The host to connect to.\n        port(int): The port to connect to.\n        fam: The string \"any\", \"ipv4\" or \"ipv6\" or an integer to pass to :func:`socket.getaddrinfo`.\n        typ: The string \"tcp\" or \"udp\" or an integer to pass to :func:`socket.getaddrinfo`.\n        timeout: A positive number, None or the string \"default\".\n        sock(:class:`socket.socket`): Socket to inherit, rather than connecting\n        ssl(bool): Wrap the socket with SSL\n        ssl_context(ssl.SSLContext): Specify SSLContext used to wrap the socket.\n        ssl_args(dict): Pass :func:`ssl.wrap_socket` named arguments in a dictionary.\n        sni(str,bool): Set 'server_hostname' in ssl_args. Set to True to set it based on the host argument. Set to False to not provide any value. Default is True.\n\n    Examples:\n\n        >>> r = remote('google.com', 443, ssl=True)\n        >>> r.send(b'GET /\\r\\n\\r\\n')\n        >>> r.recvn(4)\n        b'HTTP'\n\n        If a connection cannot be made, an exception is raised.\n\n        >>> r = remote('127.0.0.1', 1)\n        Traceback (most recent call last):\n        ...\n        PwnlibException: Could not connect to 127.0.0.1 on port 1\n\n        You can also use :meth:`.remote.fromsocket` to wrap an existing socket.\n\n        >>> import socket\n        >>> s = socket.socket()\n        >>> s.connect(('google.com', 80))\n        >>> s.send(b'GET /' + b'\\r\\n'*2)\n        9\n        >>> r = remote.fromsocket(s)\n        >>> r.recvn(4)\n        b'HTTP'\n    \"\"\"\n\n    def __init__(self, host, port,\n                 fam = \"any\", typ = \"tcp\",\n                 sock=None, ssl=False, ssl_context=None, ssl_args=None, sni=True,\n                 *args, **kwargs):\n        super(remote, self).__init__(*args, **kwargs)\n\n        # convert port to string for sagemath support\n        self.rport  = str(port)\n        self.rhost  = host\n\n        if sock:\n            self.family = sock.family\n            self.type   = sock.type\n            self.proto  = sock.proto\n            self.sock   = sock\n\n        else:\n            typ = self._get_type(typ)\n            fam = self._get_family(fam)\n            try:\n                self.sock   = self._connect(fam, typ)\n            except socket.gaierror as e:\n                if e.errno != socket.EAI_NONAME:\n                    raise\n                self.error('Could not resolve hostname: %r', host)\n        if self.sock:\n            self.settimeout(self.timeout)\n            self.lhost, self.lport = self.sock.getsockname()[:2]\n\n            if ssl:\n                # Deferred import to save startup time\n                import ssl as _ssl\n\n                ssl_args = ssl_args or {}\n                ssl_context = ssl_context or _ssl.SSLContext(_ssl.PROTOCOL_TLSv1_2)\n                if isinstance(sni, str):\n                    ssl_args[\"server_hostname\"] = sni\n                elif sni:\n                    ssl_args[\"server_hostname\"] = host\n                self.sock = ssl_context.wrap_socket(self.sock,**ssl_args)\n\n    def _connect(self, fam, typ):\n        sock    = None\n        timeout = self.timeout\n\n        with self.waitfor('Opening connection to %s on port %s' % (self.rhost, self.rport)) as h:\n            for res in socket.getaddrinfo(self.rhost, self.rport, fam, typ, 0, socket.AI_PASSIVE):\n                self.family, self.type, self.proto, _canonname, sockaddr = res\n\n                if self.type not in [socket.SOCK_STREAM, socket.SOCK_DGRAM]:\n                    continue\n\n                h.status(\"Trying %s\", sockaddr[0])\n\n                sock = socket.socket(self.family, self.type, self.proto)\n\n                if timeout is not None and timeout <= 0:\n                    sock.setblocking(0)\n                else:\n                    sock.setblocking(1)\n                    sock.settimeout(timeout)\n\n                try:\n                    sock.connect(sockaddr)\n                    return sock\n                except socks.ProxyError:\n                    raise\n                except socket.error:\n                    pass\n            self.error(\"Could not connect to %s on port %s\", self.rhost, self.rport)\n\n    @classmethod\n    def fromsocket(cls, socket):\n        \"\"\"\n        Helper method to wrap a standard python socket.socket with the\n        tube APIs.\n\n        Arguments:\n            socket: Instance of socket.socket\n\n        Returns:\n            Instance of pwnlib.tubes.remote.remote.\n        \"\"\"\n        s = socket\n        host, port = s.getpeername()\n        return remote(host, port, fam=s.family, typ=s.type, sock=s)\n\nclass tcp(remote):\n    __doc__ = remote.__doc__\n    def __init__(self, host, port, *a, **kw):\n        return super(tcp, self).__init__(host, port, typ=\"tcp\", *a, **kw)\n\nclass udp(remote):\n    __doc__ = remote.__doc__\n    def __init__(self, host, port, *a, **kw):\n        return super(udp, self).__init__(host, port, typ=\"udp\", *a, **kw)\n\nclass connect(remote):\n    __doc__ = remote.__doc__\n", "path": "pwnlib/tubes/remote.py"}]}