wesnoth_addon_manager: added IPv6 support

This commit is contained in:
Elvish_Hunter 2023-03-12 10:16:01 +01:00
parent 7e67bc5d08
commit becf628198
3 changed files with 39 additions and 15 deletions

View file

@ -16,6 +16,7 @@
### WML Engine
### Miscellaneous and Bug Fixes
* wesnoth_addon_manager now supports SSL/TLS connection (using the `--secure` flag)
* wesnoth_addon_manager now supports IPv6 connection (using the `--ipv6` flag)
## Version 1.17.13
### Add-ons client

View file

@ -46,7 +46,7 @@ class CampaignClient:
("15005", "1.4.x"),
)
def __init__(self, address = None, quiet=False, secure=False):
def __init__(self, address = None, quiet=False, secure=False, ipv6=False):
"""
Return a new connection to the campaign server at the given address.
"""
@ -64,6 +64,7 @@ class CampaignClient:
self.verbose = False
self.quiet = quiet
self.secure = secure
self.ipv6 = ipv6
if self.secure:
print("Attempting to connect to the server using SSL/TLS",
@ -72,9 +73,14 @@ class CampaignClient:
else:
self.context = None
if self.ipv6:
print("Attempting to connect to the server using IPv6",
file=sys.stderr)
if address is not None:
self.canceled = False
self.ssl_unsupported = False
self.ipv6_unsupported = False
self.error = False
s = address.split(":")
if len(s) == 2:
@ -83,8 +89,10 @@ class CampaignClient:
self.host = s[0]
self.port = self.portmap[0][0]
self.port = int(self.port)
addr = socket.getaddrinfo(self.host, self.port, socket.AF_INET,
socket.SOCK_STREAM, socket.IPPROTO_TCP)[0]
addr = socket.getaddrinfo(self.host, self.port,
socket.AF_INET6 if self.ipv6 else socket.AF_INET,
socket.SOCK_STREAM, socket.IPPROTO_TCP)[0]
if not self.quiet:
sys.stderr.write("Opening socket to %s" % address)
bfwv = dict(self.portmap).get(str(self.port))
@ -93,8 +101,18 @@ class CampaignClient:
sys.stderr.write(" for " + bfwv + "\n")
else:
sys.stderr.write("\n")
sys.stderr.write("IP address resolves to {}\n".format(addr[4][0]))
self.sock = socket.socket(addr[0], addr[1], addr[2])
self.sock.connect(addr[4])
try:
self.sock.connect(addr[4])
except OSError:
if self.ipv6:
self.ipv6_unsupported = True
else:
self.error = True
return
# the first part of the connection is unencrypted
# the client must send a packet of 4 bytes
# with a value of 1 if requesting an encrypted connection
@ -157,6 +175,8 @@ class CampaignClient:
sys.stderr.write("Canceled socket.\n")
elif self.ssl_unsupported:
sys.stderr.write("Server does not support SSL/TLS.\n")
elif self.ipv6_unsupported:
sys.stderr.write("Internet connection may not support IPv6 yet.\n")
elif self.error:
sys.stderr.write("Unexpected disconnection.\n")
else:
@ -189,7 +209,7 @@ class CampaignClient:
"""
Send binary data to the server.
"""
if self.error or self.ssl_unsupported:
if self.error or self.ssl_unsupported or self.ipv6_unsupported:
return None
# Compress the packet before we send it
@ -209,7 +229,7 @@ class CampaignClient:
"""
Read binary data from the server.
"""
if self.error or self.ssl_unsupported:
if self.error or self.ssl_unsupported or self.ipv6_unsupported:
return None
packet = b""
@ -303,7 +323,7 @@ class CampaignClient:
"""
Returns a WML object containing all available info from the server.
"""
if self.error or self.ssl_unsupported:
if self.error or self.ssl_unsupported or self.ipv6_unsupported:
return None
request = append_tag(None, "request_campaign_list")
if addon:

View file

@ -97,6 +97,9 @@ if __name__ == "__main__":
argumentparser.add_argument("-S", "--secure",
action="store_true",
help="Connect to the add-ons server using SSL/TLS encryption.")
argumentparser.add_argument("-6", "--ipv6",
action="store_true",
help="Connect to the add-ons server using IPv6 connectivity.")
args = argumentparser.parse_args()
port = args.port
@ -217,7 +220,7 @@ if __name__ == "__main__":
campaign_list = None
if args.list:
cs = CampaignClient(address, secure=args.secure)
cs = CampaignClient(address, secure=args.secure, ipv6=args.ipv6)
campaign_list = data = cs.list_campaigns()
if data:
campaigns = data.get_all(tag = "campaigns")[0]
@ -248,7 +251,7 @@ if __name__ == "__main__":
sys.stderr.write("Could not connect.\n")
elif args.download:
cs = CampaignClient(address, secure=args.secure)
cs = CampaignClient(address, secure=args.secure, ipv6=args.ipv6)
fetchlist = []
campaign_list = data = cs.list_campaigns()
if data:
@ -284,24 +287,24 @@ if __name__ == "__main__":
"because it is already up-to-date.")
elif args.unpack:
cs = CampaignClient(address, secure=args.secure)
cs = CampaignClient(address, secure=args.secure, ipv6=args.ipv6)
with open(args.unpack, "rb") as f:
data = f.read()
decoded = cs.decode(data)
print("Unpacking %s..." % args.unpack)
cs.unpackdir(decoded, args.campaigns_dir, verbose=True)
elif args.remove:
cs = CampaignClient(address, secure=args.secure)
cs = CampaignClient(address, secure=args.secure, ipv6=args.ipv6)
data = cs.delete_campaign(*args.remove)
print_messages(data)
elif args.change_passphrase:
cs = CampaignClient(address, secure=args.secure)
cs = CampaignClient(address, secure=args.secure, ipv6=args.ipv6)
data = cs.change_passphrase(*args.change_passphrase)
print_messages(data)
elif args.upload:
cs = CampaignClient(address, secure=args.secure)
cs = CampaignClient(address, secure=args.secure, ipv6=args.ipv6)
if os.path.isdir(args.upload):
# else basename returns an empty string
args.upload = args.upload.rstrip("/")
@ -376,7 +379,7 @@ if __name__ == "__main__":
cdir = args.update
dirs = glob.glob(os.path.join(cdir, "*"))
dirs = [x for x in dirs if os.path.isdir(x)]
cs = CampaignClient(address, secure=args.secure)
cs = CampaignClient(address, secure=args.secure, ipv6=args.ipv6)
campaign_list = data = cs.list_campaigns()
if not data:
sys.stderr.write("Could not connect to the add-on server.\n")
@ -430,7 +433,7 @@ if __name__ == "__main__":
if args.html:
if not campaign_list:
cs = CampaignClient(address, secure=args.secure)
cs = CampaignClient(address, secure=args.secure, ipv6=args.ipv6)
campaign_list = cs.list_campaigns()
del cs
if campaign_list: