Skip to content

Commit

Permalink
ipv6 support
Browse files Browse the repository at this point in the history
  • Loading branch information
fuktommy committed Feb 2, 2024
1 parent 6504b4c commit 0436419
Show file tree
Hide file tree
Showing 10 changed files with 74 additions and 18 deletions.
2 changes: 1 addition & 1 deletion LICENSE
@@ -1,4 +1,4 @@
Copyright (c) 2005-2022 shinGETsu Project.
Copyright (c) 2005-2024 shinGETsu Project.
All rights reserved.

Redistribution and use in source and binary forms, with or without
Expand Down
1 change: 1 addition & 0 deletions doc/sample.ini
Expand Up @@ -5,6 +5,7 @@

[Network]
# Bind Address(Default: *)
# :: for ipv6
bind_addr:

# Listening TCP port.
Expand Down
10 changes: 6 additions & 4 deletions shingetsu/LightCGIHTTPServer.py
@@ -1,7 +1,7 @@
"""Tiny HTTP server supporting threading CGI.
"""
#
# Copyright (c) 2005-2023 shinGETsu Project.
# Copyright (c) 2005-2024 shinGETsu Project.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
Expand Down Expand Up @@ -29,6 +29,7 @@
import copy
import os
import re
import socket
import sys
import urllib.parse
import http.server
Expand Down Expand Up @@ -105,6 +106,9 @@ def is_cgi(self):

def address_string(self):
host, port = self.client_address[:2]
m = re.search(r'^::ffff:([\d.]+)$', host)
if m:
return m.group(1)
return host

def log_request(self, code='-', size='-'):
Expand Down Expand Up @@ -265,6 +269,4 @@ def copyfile(self, source, outputfile):


class HTTPServer(socketserver.ThreadingMixIn, http.server.HTTPServer):
#XXX ThreadingMixIn of Python 3.7.3 does not release threads from its thread list
#XXX https://github.com/python/cpython/pull/13893
block_on_close = False
address_family = socket.AF_INET6
6 changes: 4 additions & 2 deletions shingetsu/basecgi.py
@@ -1,7 +1,7 @@
'''Base CGI module.
'''
#
# Copyright (c) 2005-2015 shinGETsu Project.
# Copyright (c) 2005-2024 shinGETsu Project.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
Expand Down Expand Up @@ -29,6 +29,8 @@
import os
import sys

from . import util

__all__ = ['CGI']


Expand Down Expand Up @@ -106,7 +108,7 @@ def start(self):
self.run()
except (IOError, socket.error, socket.timeout) as strerror:
self.stderr.write("%s: %s\n" %
(self.environ['REMOTE_ADDR'], strerror))
(util.get_http_remote_addr(self.environ), strerror))

def run(self):
"""Main routine for CGI."""
Expand Down
2 changes: 1 addition & 1 deletion shingetsu/config.py
@@ -1,7 +1,7 @@
"""Saku Configuration.
"""
#
# Copyright (c) 2005-2023 shinGETsu Project.
# Copyright (c) 2005-2024 shinGETsu Project.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
Expand Down
8 changes: 6 additions & 2 deletions shingetsu/mch/datd.py
@@ -1,7 +1,7 @@
"""2ch like dat interface
"""
#
# Copyright (c) 2014,2015 shinGETsu Project.
# Copyright (c) 2014-2024 shinGETsu Project.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
Expand Down Expand Up @@ -32,6 +32,7 @@
from wsgiref.headers import Headers
from email import utils as eutils
import collections
import socket
import socketserver

from shingetsu import cache
Expand Down Expand Up @@ -60,6 +61,9 @@
def dat_app(env, resp):
# utils.log('dat_app')
addr = env.get('REMOTE_ADDR', '')
m = re.search(r'^::ffff:([\d.]+)$', addr)
if m:
addr = m.group(1)
env['shingetsu.isadmin'] = bool(config.re_admin.match(addr))
env['shingetsu.isfriend'] = bool(config.re_friend.match(addr))
env['shingetsu.isvisitor'] = bool(config.re_visitor.match(addr))
Expand Down Expand Up @@ -291,7 +295,7 @@ def run(self):
utils.log('use wsgiref')
class Server(socketserver.ThreadingMixIn,
simple_server.WSGIServer):
pass
address_family = socket.AF_INET6
_server = simple_server.make_server('', self._port, dat_app,
server_class=Server)
_server.serve_forever()
Expand Down
5 changes: 3 additions & 2 deletions shingetsu/mch/post.py
Expand Up @@ -2,7 +2,7 @@
"""2ch like post
"""
#
# Copyright (c) 2014-2023 shinGETsu Project.
# Copyright (c) 2014-2024 shinGETsu Project.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
Expand Down Expand Up @@ -38,6 +38,7 @@
from shingetsu import updatequeue
from shingetsu import template
from shingetsu import config
from shingetsu import util

from . import dat
from . import utils
Expand Down Expand Up @@ -121,7 +122,7 @@ def post_comment_app(env, resp):
# utils.log('post_comment_app')
subject, name, mail, body, datkey = _get_comment_data(env)

info = {'host': env.get('REMOTE_ADDR', ''),
info = {'host': util.get_http_remote_addr(env),
'name': name,
'mail': mail,
'body': body}
Expand Down
1 change: 1 addition & 0 deletions shingetsu/mch/utils.py
Expand Up @@ -6,6 +6,7 @@

from shingetsu import title
from shingetsu import tag
from shingetsu import util


def log(s, *args, **kwds):
Expand Down
45 changes: 40 additions & 5 deletions shingetsu/node.py
@@ -1,7 +1,7 @@
"""Saku Node and NodeList.
"""
#
# Copyright (c) 2005-2023 shinGETsu Project.
# Copyright (c) 2005-2024 shinGETsu Project.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
Expand Down Expand Up @@ -124,15 +124,19 @@ class Node:
"""One unit for P2P."""

nodestr = None
isv6 = False

def __init__(self, nodestr=None, host="", port="", path=""):
if nodestr is not None:
nodestr = nodestr.strip()
if not re.search(r"\d+/[^: ]+$", nodestr):
raise NodeError('bad format')
self.nodestr = nodestr.replace('+', '/')
elif ':' in host:
self.nodestr = '[%s]:%s%s' % (host, str(port), re.sub(r"\+", "/", path))
else:
self.nodestr = host + ":" + str(port) + re.sub(r"\+", "/", path)
self.nodestr = '%s:%s%s' % (host, str(port), re.sub(r"\+", "/", path))
self.isv6 = self.nodestr.startswith('[')

def __str__(self):
return self.nodestr
Expand Down Expand Up @@ -250,6 +254,12 @@ def sync(self):
def random(self):
return random.choice(self)

def filterv4(self):
return [i for i in self if not i.isv6]

def filterv6(self):
return [i for i in self if i.isv6]

def append(self, node):
if node_allow().check(str(node)):
pass
Expand Down Expand Up @@ -295,7 +305,25 @@ def myself(self):
res = n.talk('ping')
lines = iter(res)
buf = (next(lines), next(lines))
if buf[0].strip() == 'PONG':
if buf[0].strip() == 'PONG' and ':' not in buf[1]:
return Node(host=buf[1].strip(), port=port, path=path)
except StopIteration:
sys.stderr.write('/ping %s: error\n' % n)
return None

def myself6(self):
"""Who am I. (IPv6)"""
port = config.port
path = config.server
dnsname = config.dnsname
if dnsname != "":
return Node(host=dnsname, port=port, path=path)
for n in self:
try:
res = n.talk('ping')
lines = iter(res)
buf = (next(lines), next(lines))
if buf[0].strip() == 'PONG' and ':' in buf[1]:
return Node(host=buf[1].strip(), port=port, path=path)
except StopIteration:
sys.stderr.write('/ping %s: error\n' % n)
Expand Down Expand Up @@ -340,6 +368,9 @@ def init(self):
myself = self.myself()
if myself and (myself in self):
self.remove(myself)
myself6 = self.myself6()
if myself6 and (myself6 in self):
self.remove(myself6)
if len(self) == 0:
return

Expand All @@ -366,8 +397,12 @@ def init(self):
self.remove(inode)
elif len(self) <= 1:
sys.stderr.write("Warning: Few linked nodes.\n")
while len(self) > config.nodes:
n = self.random()
while len(self.filterv4()) > config.nodes:
n = random.choice(self.filterv4())
n.bye()
self.remove(n)
while len(self.filterv6()) > config.nodes:
n = random.choice(self.filterv6())
n.bye()
self.remove(n)

Expand Down
12 changes: 11 additions & 1 deletion shingetsu/util.py
@@ -1,7 +1,7 @@
"""Utilities.
"""
#
# Copyright (c) 2014 shinGETsu Project.
# Copyright (c) 2014-2024 shinGETsu Project.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
Expand All @@ -28,6 +28,7 @@

import hashlib
import os.path
import re
import sys
from . import config

Expand Down Expand Up @@ -76,6 +77,15 @@ def opentext(path, mode='r'):
newline=newline)

def get_http_remote_addr(env):
addr = get_http_remote_addr_from_env(env)
if not addr:
return addr
m = re.search(r'^::ffff:([\d.]+)$', addr)
if m:
return m.group(1)
return addr

def get_http_remote_addr_from_env(env):
if not config.use_x_forwarded_for:
return env['REMOTE_ADDR']
else:
Expand Down

0 comments on commit 0436419

Please sign in to comment.