prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  Locust insists on using IPv6 despite being in an IPv4 stack.
  ### Prerequisites
  
  - [X] I am using [the latest version of Locust](https://github.com/locustio/locust/releases/)
  - [X] I am reporting a bug, not asking a question
  
  ### Description
  
  I have an environment that is IPv4-only, but there is an IPv6 address listed in /etc/hosts. When I try to connect to the master using the following command, it results in an error:
  
  ```
  # locust -f ./p4_basic_code.py --worker --master-host locust-master -L DEBUG
  [2024-04-25 06:24:31,138] ip-192-168-0-235.ap-northeast-3.compute.internal/DEBUG/locust.runners: Failed to connect to master locust-master:5557, retry 1/60.
  ```
  
  By changing [self.socket.setsockopt(zmq.IPV6, 1)](https://github.com/locustio/locust/blob/master/locust/rpc/zmqrpc.py#L18) to 0 resolves the issue.
  ```
  # cat /etc/hosts
  127.0.0.1 localhost
  192.168.0.235 ip-192-168-0-235.ap-northeast-3.compute.internal
  127.255.0.1 locust-master
  2600:f0f0:0:0:0:0:0:1 locust-master
  ```
  
  I recommend detecting whether the current environment supports IPv6 before enabling it.
  
  ### Command line
  
  locust -f ./p4_basic_code.py --worker --master-host locust-master -L DEBUG
  
  ### Locustfile contents
  
  ```python3
  N/A
  ```
  
  
  ### Python version
  
  3.11
  
  ### Locust version
  
  2.26.0
  
  ### Operating system
  
  Debian 12
  
  </issue>
  <code>
  [start of locust/rpc/zmqrpc.py]
  1 from locust.exception import RPCError, RPCReceiveError, RPCSendError
  2 from locust.util.exception_handler import retry
  3 
  4 import msgpack.exceptions as msgerr
  5 import zmq.error as zmqerr
  6 import zmq.green as zmq
  7 
  8 from .protocol import Message
  9 
  10 
  11 class BaseSocket:
  12     def __init__(self, sock_type):
  13         context = zmq.Context()
  14         self.socket = context.socket(sock_type)
  15 
  16         self.socket.setsockopt(zmq.TCP_KEEPALIVE, 1)
  17         self.socket.setsockopt(zmq.TCP_KEEPALIVE_IDLE, 30)
  18         self.socket.setsockopt(zmq.IPV6, 1)
  19 
  20     @retry()
  21     def send(self, msg):
  22         try:
  23             self.socket.send(msg.serialize(), zmq.NOBLOCK)
  24         except zmqerr.ZMQError as e:
  25             raise RPCSendError("ZMQ sent failure") from e
  26 
  27     @retry()
  28     def send_to_client(self, msg):
  29         try:
  30             self.socket.send_multipart([msg.node_id.encode(), msg.serialize()])
  31         except zmqerr.ZMQError as e:
  32             raise RPCSendError("ZMQ sent failure") from e
  33 
  34     def recv(self):
  35         try:
  36             data = self.socket.recv()
  37             msg = Message.unserialize(data)
  38         except msgerr.ExtraData as e:
  39             raise RPCReceiveError("ZMQ interrupted message") from e
  40         except zmqerr.ZMQError as e:
  41             raise RPCError("ZMQ network broken") from e
  42         return msg
  43 
  44     def recv_from_client(self):
  45         try:
  46             data = self.socket.recv_multipart()
  47             addr = data[0].decode()
  48         except UnicodeDecodeError as e:
  49             raise RPCReceiveError("ZMQ interrupted or corrupted message") from e
  50         except zmqerr.ZMQError as e:
  51             raise RPCError("ZMQ network broken") from e
  52         try:
  53             msg = Message.unserialize(data[1])
  54         except (UnicodeDecodeError, msgerr.ExtraData) as e:
  55             raise RPCReceiveError("ZMQ interrupted or corrupted message", addr=addr) from e
  56         return addr, msg
  57 
  58     def close(self, linger=None):
  59         self.socket.close(linger=linger)
  60 
  61 
  62 class Server(BaseSocket):
  63     def __init__(self, host, port):
  64         BaseSocket.__init__(self, zmq.ROUTER)
  65         if port == 0:
  66             self.port = self.socket.bind_to_random_port(f"tcp://{host}")
  67         else:
  68             try:
  69                 self.socket.bind("tcp://%s:%i" % (host, port))
  70                 self.port = port
  71             except zmqerr.ZMQError as e:
  72                 raise RPCError(f"Socket bind failure: {e}")
  73 
  74 
  75 class Client(BaseSocket):
  76     def __init__(self, host, port, identity):
  77         BaseSocket.__init__(self, zmq.DEALER)
  78         self.socket.setsockopt(zmq.IDENTITY, identity.encode())
  79         self.socket.connect("tcp://%s:%i" % (host, port))
  80
  [end of locust/rpc/zmqrpc.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/locust/rpc/zmqrpc.py b/locust/rpc/zmqrpc.py
  --- a/locust/rpc/zmqrpc.py
  +++ b/locust/rpc/zmqrpc.py
  @@ -4,6 +4,7 @@
   import msgpack.exceptions as msgerr
   import zmq.error as zmqerr
   import zmq.green as zmq
  +from urllib3.util.connection import HAS_IPV6
   
   from .protocol import Message
   
  @@ -15,7 +16,8 @@
   
           self.socket.setsockopt(zmq.TCP_KEEPALIVE, 1)
           self.socket.setsockopt(zmq.TCP_KEEPALIVE_IDLE, 30)
  -        self.socket.setsockopt(zmq.IPV6, 1)
  +        if HAS_IPV6:
  +            self.socket.setsockopt(zmq.IPV6, 1)
   
       @retry()
       def send(self, msg):
  
verification_info: {"golden_diff": "diff --git a/locust/rpc/zmqrpc.py b/locust/rpc/zmqrpc.py\n--- a/locust/rpc/zmqrpc.py\n+++ b/locust/rpc/zmqrpc.py\n@@ -4,6 +4,7 @@\n import msgpack.exceptions as msgerr\n import zmq.error as zmqerr\n import zmq.green as zmq\n+from urllib3.util.connection import HAS_IPV6\n \n from .protocol import Message\n \n@@ -15,7 +16,8 @@\n \n         self.socket.setsockopt(zmq.TCP_KEEPALIVE, 1)\n         self.socket.setsockopt(zmq.TCP_KEEPALIVE_IDLE, 30)\n-        self.socket.setsockopt(zmq.IPV6, 1)\n+        if HAS_IPV6:\n+            self.socket.setsockopt(zmq.IPV6, 1)\n \n     @retry()\n     def send(self, msg):\n", "issue": "Locust insists on using IPv6 despite being in an IPv4 stack.\n### Prerequisites\r\n\r\n- [X] I am using [the latest version of Locust](https://github.com/locustio/locust/releases/)\r\n- [X] I am reporting a bug, not asking a question\r\n\r\n### Description\r\n\r\nI have an environment that is IPv4-only, but there is an IPv6 address listed in /etc/hosts. When I try to connect to the master using the following command, it results in an error:\r\n\r\n```\r\n# locust -f ./p4_basic_code.py --worker --master-host locust-master -L DEBUG\r\n[2024-04-25 06:24:31,138] ip-192-168-0-235.ap-northeast-3.compute.internal/DEBUG/locust.runners: Failed to connect to master locust-master:5557, retry 1/60.\r\n```\r\n\r\nBy changing [self.socket.setsockopt(zmq.IPV6, 1)](https://github.com/locustio/locust/blob/master/locust/rpc/zmqrpc.py#L18) to 0 resolves the issue.\r\n```\r\n# cat /etc/hosts\r\n127.0.0.1 localhost\r\n192.168.0.235 ip-192-168-0-235.ap-northeast-3.compute.internal\r\n127.255.0.1 locust-master\r\n2600:f0f0:0:0:0:0:0:1 locust-master\r\n```\r\n\r\nI recommend detecting whether the current environment supports IPv6 before enabling it.\r\n\r\n### Command line\r\n\r\nlocust -f ./p4_basic_code.py --worker --master-host locust-master -L DEBUG\r\n\r\n### Locustfile contents\r\n\r\n```python3\r\nN/A\r\n```\r\n\r\n\r\n### Python version\r\n\r\n3.11\r\n\r\n### Locust version\r\n\r\n2.26.0\r\n\r\n### Operating system\r\n\r\nDebian 12\n", "before_files": [{"content": "from locust.exception import RPCError, RPCReceiveError, RPCSendError\nfrom locust.util.exception_handler import retry\n\nimport msgpack.exceptions as msgerr\nimport zmq.error as zmqerr\nimport zmq.green as zmq\n\nfrom .protocol import Message\n\n\nclass BaseSocket:\n    def __init__(self, sock_type):\n        context = zmq.Context()\n        self.socket = context.socket(sock_type)\n\n        self.socket.setsockopt(zmq.TCP_KEEPALIVE, 1)\n        self.socket.setsockopt(zmq.TCP_KEEPALIVE_IDLE, 30)\n        self.socket.setsockopt(zmq.IPV6, 1)\n\n    @retry()\n    def send(self, msg):\n        try:\n            self.socket.send(msg.serialize(), zmq.NOBLOCK)\n        except zmqerr.ZMQError as e:\n            raise RPCSendError(\"ZMQ sent failure\") from e\n\n    @retry()\n    def send_to_client(self, msg):\n        try:\n            self.socket.send_multipart([msg.node_id.encode(), msg.serialize()])\n        except zmqerr.ZMQError as e:\n            raise RPCSendError(\"ZMQ sent failure\") from e\n\n    def recv(self):\n        try:\n            data = self.socket.recv()\n            msg = Message.unserialize(data)\n        except msgerr.ExtraData as e:\n            raise RPCReceiveError(\"ZMQ interrupted message\") from e\n        except zmqerr.ZMQError as e:\n            raise RPCError(\"ZMQ network broken\") from e\n        return msg\n\n    def recv_from_client(self):\n        try:\n            data = self.socket.recv_multipart()\n            addr = data[0].decode()\n        except UnicodeDecodeError as e:\n            raise RPCReceiveError(\"ZMQ interrupted or corrupted message\") from e\n        except zmqerr.ZMQError as e:\n            raise RPCError(\"ZMQ network broken\") from e\n        try:\n            msg = Message.unserialize(data[1])\n        except (UnicodeDecodeError, msgerr.ExtraData) as e:\n            raise RPCReceiveError(\"ZMQ interrupted or corrupted message\", addr=addr) from e\n        return addr, msg\n\n    def close(self, linger=None):\n        self.socket.close(linger=linger)\n\n\nclass Server(BaseSocket):\n    def __init__(self, host, port):\n        BaseSocket.__init__(self, zmq.ROUTER)\n        if port == 0:\n            self.port = self.socket.bind_to_random_port(f\"tcp://{host}\")\n        else:\n            try:\n                self.socket.bind(\"tcp://%s:%i\" % (host, port))\n                self.port = port\n            except zmqerr.ZMQError as e:\n                raise RPCError(f\"Socket bind failure: {e}\")\n\n\nclass Client(BaseSocket):\n    def __init__(self, host, port, identity):\n        BaseSocket.__init__(self, zmq.DEALER)\n        self.socket.setsockopt(zmq.IDENTITY, identity.encode())\n        self.socket.connect(\"tcp://%s:%i\" % (host, port))\n", "path": "locust/rpc/zmqrpc.py"}]}