stem + ipv6 = " Nickname in the circuit path is malformed (%s)' % nickname"
I got this trace at the konsole :
tfoerste@tor-relay ~ $ Exception in thread Event Notifier:
Traceback (most recent call last):
File "/usr/lib64/python3.3/site-packages/stem/response/events.py", line 844, in _parse
stem.control._parse_circ_entry(self.endpoint)
File "/usr/lib64/python3.3/site-packages/stem/control.py", line 3601, in _parse_circ_entry
raise stem.ProtocolError('Nickname in the circuit path is malformed (%s)' % nickname)
stem.ProtocolError: Nickname in the circuit path is malformed (2607:ff58::d053:df22:52773)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/lib64/python3.3/threading.py", line 901, in _bootstrap_inner
self.run()
File "/usr/lib64/python3.3/threading.py", line 858, in run
self._target(*self._args, **self._kwargs)
File "/usr/lib64/python3.3/site-packages/stem/control.py", line 882, in _event_loop
self._handle_event(event_message)
File "/usr/lib64/python3.3/site-packages/stem/control.py", line 3474, in _handle_event
stem.response.convert('EVENT', event_message, arrived_at = time.time())
File "/usr/lib64/python3.3/site-packages/stem/response/__init__.py", line 135, in convert
message._parse_message(**kwargs)
File "/usr/lib64/python3.3/site-packages/stem/response/events.py", line 66, in _parse_message
self._parse()
File "/usr/lib64/python3.3/site-packages/stem/response/events.py", line 852, in _parse
raise stem.ProtocolError("ORCONN's endpoint location's port is invalid: %s" % self)
stem.ProtocolError: ORCONN's endpoint location's port is invalid: ORCONN 2607:ff58::d053:df22:52773 NEW ID=937797
``` using stem-1.4.1 at a hardened Gentoo Linux for this script : ```
tfoerste@tor-relay ~ $ cat info.py
#!/usr/bin/python3 -u
#
# Toralf Foerster
# Hamburg
# Germany
from collections import Counter
from stem.control import Controller
from stem.util.system import pid_by_name
from stem.util.connection import get_connections, system_resolvers, port_usage
def main():
with Controller.from_port(port = 9051) as controller:
controller.authenticate()
# might become a feature
#
try:
desc = controller.get_microdescriptor()
print (" flags : %s" % desc.flags())
print (" measured bandwidth : %i" % desc.measured())
except Exception as Exc:
#print Exc
pass
# store here the tupel <ip address, ORport> of already known relays
#
relays = {}
myflags = {}
for desc in controller.get_network_statuses():
relays.setdefault(desc.address, []).append(desc.or_port)
if desc.nickname == 'zwiebeltoralf':
myflags = desc.flags
ProcessName = 'tor'
pid = pid_by_name(ProcessName)
resolver = system_resolvers()[0]
connections = get_connections(resolver, process_pid = pid, process_name = ProcessName)
# classify connections
#
class Country(Counter):
def __init__(self, name="<none>"):
self.name = name
def __str__(self):
ret=""
d = self.most_common(8)
for tupel in d:
ret += "%s%3i " % (tupel)
return " %-16s - %4i %s" % (self.name, sum(self.values()), ret)
class Port(Counter):
def __str__(self):
# TODO: return "\n".join(map(func, self.keys()))
ret = ""
for port in sorted(self.keys()):
ret += " %14i ... %4i (%s)\n" % (port, self[port], port_usage(port))
return ret.rstrip("\n")
relay2localDirPort = Country(name="DirPort <= relay")
relay2localORPort = Country(name="ORPort <= relay")
relayFromRemoteORPort = Country(name="=> relay ORPort")
relayFromOther = Country(name="=> relay port")
relayPorts = Port()
other2localDirPort = Country(name="DirPort <= other")
other2localORPort = Country(name="ORPort <= other")
nonExit = Country(name="=> non exit port")
nonExitPorts = Port()
Exit = Country(name="=> exit port")
ExitPorts = Port()
try:
policy = controller.get_exit_policy()
except Exception as Exc:
# there's currently an issue with ipv6 key words
nonExit.name = 'non+exit port'
torORPort = int(controller.get_conf("ORPort"))
torDirPort = int(controller.get_conf("DirPort"))
for conn in connections:
laddr, raddr = conn.local_address, conn.remote_address
if (raddr == '0.0.0.0') | (laddr == '127.0.0.1'):
continue
lport, rport = conn.local_port, conn.remote_port
country = controller.get_info("ip-to-country/%s" % raddr, 'unkown')
if raddr in relays:
if lport == torORPort:
relay2localORPort[country] += 1
elif lport == torDirPort:
relay2localDirPort[country] += 1
elif rport in relays[raddr]:
relayFromRemoteORPort[country] += 1
else:
# a relay w/ an additional service at a dedicated port
#
relayFromOther[country] += 1
relayPorts[rport] += 1
else:
if lport == torDirPort:
other2localDirPort[country] += 1
elif lport == torORPort:
other2localORPort[country] += 1
else:
try:
if policy.can_exit_to(raddr, rport):
Exit[country] += 1
ExitPorts[rport] += 1
else:
nonExit[country] += 1
nonExitPorts[rport] += 1
except Exception as Exc:
nonExit[country] += 1
nonExitPorts[rport] += 1
print (" %-16s %5i %s" % ("overall", len(connections), " ".join(myflags)))
print (relay2localDirPort)
print (relay2localORPort)
print (relayFromRemoteORPort)
print (relayFromOther)
if (sum(relayFromOther.values()) > 0):
print (relayPorts)
print (other2localDirPort)
print (other2localORPort)
print (nonExit)
if (sum (nonExit.values()) > 0):
print (nonExitPorts)
print (Exit)
if (sum (Exit.values()) > 0):
print (ExitPorts)
if __name__ == '__main__':
main()