2424
2525PROTO_VERSION = 60002
2626CADDR_TIME_VERSION = 31402
27+ IPV4_COMPAT = b"\x00 " * 10 + b"\xff " * 2
28+
2729
2830class CAddress (Serializable ):
2931 def __init__ (self , protover = PROTO_VERSION ):
3032 self .protover = protover
3133 self .nTime = 0
3234 self .nServices = 1
33- self .pchReserved = b" \x00 " * 10 + b" \xff " * 2
35+ self .pchReserved = IPV4_COMPAT
3436 self .ip = "0.0.0.0"
3537 self .port = 0
3638
@@ -40,19 +42,35 @@ def stream_deserialize(cls, f, without_time=False):
4042 if c .protover >= CADDR_TIME_VERSION and not without_time :
4143 c .nTime = struct .unpack (b"<I" , ser_read (f , 4 ))[0 ]
4244 c .nServices = struct .unpack (b"<Q" , ser_read (f , 8 ))[0 ]
43- c .pchReserved = ser_read (f , 12 )
44- c .ip = socket .inet_ntoa (ser_read (f , 4 ))
45+
46+ packedIP = ser_read (f , 16 )
47+
48+ if bytes (packedIP [0 :12 ]) == IPV4_COMPAT : # IPv4
49+ c .ip = socket .inet_ntop (socket .AF_INET , packedIP [12 :16 ])
50+ else : #IPv6
51+ c .ip = socket .inet_ntop (socket .AF_INET6 , packedIP )
52+
4553 c .port = struct .unpack (b">H" , ser_read (f , 2 ))[0 ]
4654 return c
4755
56+
4857 def stream_serialize (self , f , without_time = False ):
4958 if self .protover >= CADDR_TIME_VERSION and not without_time :
5059 f .write (struct .pack (b"<I" , self .nTime ))
5160 f .write (struct .pack (b"<Q" , self .nServices ))
52- f .write (self .pchReserved )
53- f .write (socket .inet_aton (self .ip ))
61+
62+ protocol = socket .AF_INET
63+ if ":" in self .ip : # determine if address is IPv6
64+ f .write (socket .inet_pton (socket .AF_INET6 , self .ip ))
65+ else :
66+ f .write (self .pchReserved )
67+ f .write (socket .inet_pton (socket .AF_INET , self .ip ))
68+
5469 f .write (struct .pack (b">H" , self .port ))
5570
71+
72+
73+
5674 def __repr__ (self ):
5775 return "CAddress(nTime=%d nServices=%i ip=%s port=%i)" % (self .nTime , self .nServices , self .ip , self .port )
5876
0 commit comments