diff --git a/docs/setup/initial_config.rst b/docs/setup/initial_config.rst index 9330208..26b83ad 100644 --- a/docs/setup/initial_config.rst +++ b/docs/setup/initial_config.rst @@ -38,7 +38,9 @@ Instance Configuration ["dickson.freenode.net", 6667], ["morgan.freenode.net", 6667] ], - "ipv6":"off" + "force_ipv6": false, + "force_ipv4": false, + "bind": ["1.2.3.4", 5678] }, "modules":[ "PingResponder", @@ -78,9 +80,22 @@ options: the bot must reconnect to the IRC server later, the next server will be used. -.. cmdoption:: connection.ipv6 +.. cmdoption:: connection.force_ipv6 - Enable or disable defaulting to IPv6 using the value "off" or "on" + Enable this option to force use of ipv6 connections and ignore ipv4 server addresses. + +.. cmdoption:: connection.force_ipv4 + + Enable this option to force use of ipv4 connections and ignore ipv6 server addresses. Enabling force_ipv6 + overrides force_ipv4. + +.. cmdoption:: connection.bind + + Set the local address and port to bind the connection to. + +.. note:: + + To bind to an address but no specific port, set the second tuple entry to `null`. .. cmdoption:: modules diff --git a/examples/config.json b/examples/config.json index b2119d4..0c629b5 100644 --- a/examples/config.json +++ b/examples/config.json @@ -1,23 +1,23 @@ { - "bot":{ - "datadir":"./data/", - "rpcbind":"0.0.0.0", - "rpcport":1876, - "usermodules": [ "./data/modules/" ] - }, - "connection":{ - "servers": [ - ["weber.freenode.net", 6667], - ["asimov.freenode.net", 6667], - ["card.freenode.net", 6667], - ["dickson.freenode.net", 6667], - ["morgan.freenode.net", 6667] - ], - "ipv6":"off", - }, - "modules":[ - "PingResponder", - "Services", - "UserModule" - ] + "bot":{ + "datadir":"./data/", + "rpcbind":"0.0.0.0", + "rpcport":1876, + "usermodules": [ "./data/modules/" ] + }, + "connection":{ + "servers": [ + ["weber.freenode.net", 6667], + ["asimov.freenode.net", 6667], + ["card.freenode.net", 6667], + ["dickson.freenode.net", 6667], + ["morgan.freenode.net", 6667] + ], + "force_ipv6": false + }, + "modules":[ + "PingResponder", + "Services", + "UserModule" + ] } diff --git a/pyircbot/irccore.py b/pyircbot/irccore.py index 902afba..9ff5749 100644 --- a/pyircbot/irccore.py +++ b/pyircbot/irccore.py @@ -43,8 +43,12 @@ class IRCCore(object): """List of server address""" self.port = 0 """Server port""" - self.ipv6 = False - """Use IPv6?""" + self.connection_family = socket.AF_UNSPEC + """Socket family. 0 will auto-detect ipv4 or v6. Change this to socket.AF_INET or socket.AF_INET6 force use of + ipv4 or ipv6.""" + + self.bind_addr = None + """Optionally bind to a specific address. This should be a (host, port) tuple.""" # Set up hooks for modules self.initHooks() @@ -56,7 +60,9 @@ class IRCCore(object): self.reader, self.writer = await asyncio.open_connection(self.servers[self.server][0], port=self.servers[self.server][1], loop=loop, - ssl=None) + ssl=None, + family=self.connection_family, + local_addr=self.bind_addr) self.fire_hook("_CONNECT") except (socket.gaierror, ConnectionRefusedError): traceback.print_exc() diff --git a/pyircbot/pyircbot.py b/pyircbot/pyircbot.py index 2bd708b..2c82b26 100644 --- a/pyircbot/pyircbot.py +++ b/pyircbot/pyircbot.py @@ -11,6 +11,7 @@ import sys from pyircbot.rpc import BotRPC from pyircbot.irccore import IRCCore from collections import namedtuple +from socket import AF_INET, AF_INET6 import os.path import asyncio @@ -42,6 +43,11 @@ class PyIRCBot(object): """IRC protocol handler""" self.irc = IRCCore(servers=self.botconfig["connection"]["servers"]) + if self.botconfig.get("connection").get("force_ipv6", False): + self.irc.connection_family = AF_INET6 + elif self.botconfig.get("connection").get("force_ipv4", False): + self.irc.connection_family = AF_INET + self.irc.bind_addr = self.botconfig.get("connection").get("bind", None) # legacy support self.act_PONG = self.irc.act_PONG