@@ -18,15 +18,37 @@ _ipaddr = ipaddress.ip_address
18
18
_ipnet = ipaddress.ip_network
19
19
20
20
21
- cdef inline _net_encode(WriteBuffer buf, int32_t version, uint8_t bits,
21
+ cdef inline uint8_t _ip_max_prefix_len(int32_t family):
22
+ # Maximum number of bits in the network prefix of the specified
23
+ # IP protocol version.
24
+ if family == PGSQL_AF_INET:
25
+ return 32
26
+ else :
27
+ return 128
28
+
29
+
30
+ cdef inline int32_t _ip_addr_len(int32_t family):
31
+ # Length of address in bytes for the specified IP protocol version.
32
+ if family == PGSQL_AF_INET:
33
+ return 4
34
+ else :
35
+ return 16
36
+
37
+
38
+ cdef inline int8_t _ver_to_family(int32_t version):
39
+ if version == 4 :
40
+ return PGSQL_AF_INET
41
+ else :
42
+ return PGSQL_AF_INET6
43
+
44
+
45
+ cdef inline _net_encode(WriteBuffer buf, int8_t family, uint32_t bits,
22
46
int8_t is_cidr, bytes addr):
23
47
24
48
cdef:
25
49
char * addrbytes
26
50
ssize_t addrlen
27
- int8_t family
28
51
29
- family = PGSQL_AF_INET if version == 4 else PGSQL_AF_INET6
30
52
cpython.PyBytes_AsStringAndSize(addr, & addrbytes, & addrlen)
31
53
32
54
buf.write_int32(4 + < int32_t> addrlen)
@@ -41,28 +63,31 @@ cdef net_decode(ConnectionSettings settings, FastReadBuffer buf):
41
63
cdef:
42
64
int32_t family = < int32_t> buf.read(1 )[0 ]
43
65
uint8_t bits = < uint8_t> buf.read(1 )[0 ]
44
- uint32_t is_cidr = < uint32_t > buf.read(1 )[0 ]
45
- uint32_t addrlen = < uint32_t > buf.read(1 )[0 ]
66
+ int32_t is_cidr = < int32_t > buf.read(1 )[0 ]
67
+ int32_t addrlen = < int32_t > buf.read(1 )[0 ]
46
68
bytes addr
69
+ uint8_t max_prefix_len = _ip_max_prefix_len(family)
47
70
48
71
if family != PGSQL_AF_INET and family != PGSQL_AF_INET6:
49
72
raise ValueError (' invalid address family in "{}" value' .format(
50
73
' cidr' if is_cidr else ' inet'
51
74
))
52
75
53
- if bits > (32 if family == PGSQL_AF_INET else 128 ):
54
- raise ValueError (' invalid bits in "{}" value' .format(
76
+ max_prefix_len = _ip_max_prefix_len(family)
77
+
78
+ if bits > max_prefix_len:
79
+ raise ValueError (' invalid network prefix length in "{}" value' .format(
55
80
' cidr' if is_cidr else ' inet'
56
81
))
57
82
58
- if addrlen != ( 4 if family == PGSQL_AF_INET else 16 ):
59
- raise ValueError (' invalid length in "{}" value' .format(
83
+ if addrlen != _ip_addr_len( family):
84
+ raise ValueError (' invalid address length in "{}" value' .format(
60
85
' cidr' if is_cidr else ' inet'
61
86
))
62
87
63
88
addr = cpython.PyBytes_FromStringAndSize(buf.read(addrlen), addrlen)
64
89
65
- if is_cidr or bits > 0 :
90
+ if is_cidr or bits ! = max_prefix_len :
66
91
return _ipnet(addr).supernet(new_prefix = cpython.PyLong_FromLong(bits))
67
92
else :
68
93
return _ipaddr(addr)
@@ -71,15 +96,17 @@ cdef net_decode(ConnectionSettings settings, FastReadBuffer buf):
71
96
cdef cidr_encode(ConnectionSettings settings, WriteBuffer buf, obj):
72
97
cdef:
73
98
object ipnet
99
+ int8_t family
74
100
75
101
ipnet = _ipnet(obj)
76
- _net_encode(buf, ipnet.version, ipnet.prefixlen, 1 ,
77
- ipnet.network_address.packed)
102
+ family = _ver_to_family( ipnet.version)
103
+ _net_encode(buf, family, ipnet.prefixlen, 1 , ipnet.network_address.packed)
78
104
79
105
80
106
cdef inet_encode(ConnectionSettings settings, WriteBuffer buf, obj):
81
107
cdef:
82
108
object ipaddr
109
+ int8_t family
83
110
84
111
try :
85
112
ipaddr = _ipaddr(obj)
@@ -88,7 +115,8 @@ cdef inet_encode(ConnectionSettings settings, WriteBuffer buf, obj):
88
115
# for the host datatype.
89
116
cidr_encode(settings, buf, obj)
90
117
else :
91
- _net_encode(buf, ipaddr.version, 0 , 0 , ipaddr.packed)
118
+ family = _ver_to_family(ipaddr.version)
119
+ _net_encode(buf, family, _ip_max_prefix_len(family), 0 , ipaddr.packed)
92
120
93
121
94
122
cdef init_network_codecs():
0 commit comments