118 Construct using given literal IPv4 address and TCP/UDP port |
123 Construct using given literal IPv4 address and TCP/UDP port |
119 |
124 |
120 addr - IPv4 address, defaults to INADDR_ANY (0.0.0.0) |
125 addr - IPv4 address, defaults to INADDR_ANY (0.0.0.0) |
121 port - TCP/UDP port, defaults to 0 (ephemeral) |
126 port - TCP/UDP port, defaults to 0 (ephemeral) |
122 """ |
127 """ |
|
128 |
|
129 # zero |
|
130 libc.memset(&self.sockaddr, 0, sizeof(self.sockaddr)) |
123 |
131 |
124 # store our family |
132 # store our family |
125 # XXX: this should be a class attribute... |
133 # XXX: this should be a class attribute... |
126 self._init_family(platform.AF_INET) |
134 self._init_family(platform.AF_INET) |
127 |
135 |
160 """ |
168 """ |
161 |
169 |
162 def __get__ (self) : |
170 def __get__ (self) : |
163 return platform.ntohs(self.sockaddr.sin_port) |
171 return platform.ntohs(self.sockaddr.sin_port) |
164 |
172 |
|
173 def __cmp__ (self, other_obj) : |
|
174 """ |
|
175 A sockaddr_in is equal to any other sockaddr_in which has the same addr and port |
|
176 |
|
177 >>> assert sockaddr_in() == sockaddr_in() |
|
178 >>> assert sockaddr_in('127.0.0.1', 80) == sockaddr_in('127.0.0.1', 80) |
|
179 >>> addr = sockaddr_in(); assert addr == addr |
|
180 """ |
|
181 |
|
182 if not isinstance(other_obj, sockaddr_in) : |
|
183 return <object> py.Py_NotImplemented |
|
184 |
|
185 cdef sockaddr_in other = other_obj |
|
186 cdef platform.sockaddr_in *sa1 = &self.sockaddr, *sa2 = &other.sockaddr |
|
187 |
|
188 if other is self : |
|
189 return 0 |
|
190 |
|
191 return ( |
|
192 libc.memcmp(<void *> &sa1.sin_port, <void *> &sa2.sin_port, sizeof(sa1.sin_port)) |
|
193 or libc.memcmp(<void *> &sa1.sin_addr, <void *> &sa2.sin_addr, sizeof(sa1.sin_addr)) |
|
194 ) |
|
195 |
165 def __str__ (self) : |
196 def __str__ (self) : |
166 """ |
197 """ |
167 Return the literal ASCII representation for this sockaddr as an '<addr>:<port> string |
198 Return the literal ASCII representation for this sockaddr as an '<addr>:<port> string |
|
199 |
|
200 >>> str(sockaddr_in()) |
|
201 '0.0.0.0:0' |
168 """ |
202 """ |
169 |
203 |
170 # format |
204 # format |
171 return "%s:%s" % self.getnameinfo() |
205 return "%s:%s" % self.getnameinfo() |
172 |
206 |
179 '::1' |
213 '::1' |
180 >>> sa6.port |
214 >>> sa6.port |
181 80 |
215 80 |
182 >>> str(sa6) |
216 >>> str(sa6) |
183 '[::1]:80' |
217 '[::1]:80' |
184 >>> str(sockaddr_in6()) |
218 |
185 '[::]:0' |
|
186 """ |
219 """ |
187 |
220 |
188 cdef platform.sockaddr_in6 sockaddr |
221 cdef platform.sockaddr_in6 sockaddr |
189 |
222 |
190 def __init__ (self, object addr=None, platform.in_port_t port=0) : |
223 def __init__ (self, object addr=None, platform.in_port_t port=0, unsigned int scope_id = 0) : |
191 """ |
224 """ |
192 Construct using given literal IPv6 address and TCP/UDP port |
225 Construct using given literal IPv6 address and TCP/UDP port |
193 |
226 |
194 addr - IPv6 address, defaults to platform.in6addr_any (::) |
227 addr - IPv6 address, defaults to platform.in6addr_any (::) |
195 port - TCP/UDP port, defaults to 0 (ephemeral) |
228 port - TCP/UDP port, defaults to 0 (ephemeral) |
196 """ |
229 scope_id - (optional) scope ID representing interface index for link-local addresses |
|
230 """ |
|
231 |
|
232 # zero |
|
233 libc.memset(&self.sockaddr, 0, sizeof(self.sockaddr)) |
197 |
234 |
198 # store our family |
235 # store our family |
199 # XXX: this should be a class attribute... |
236 # XXX: this should be a class attribute... |
200 self._init_family(platform.AF_INET6) |
237 self._init_family(platform.AF_INET6) |
201 |
238 |
228 |
268 |
229 libc.memcpy(&self.sockaddr, sa, sa_len) |
269 libc.memcpy(&self.sockaddr, sa, sa_len) |
230 |
270 |
231 property port : |
271 property port : |
232 """ |
272 """ |
233 The integer port number |
273 The integer port number. |
|
274 |
|
275 This will represent it correctly in host byte order. |
234 """ |
276 """ |
235 |
277 |
236 def __get__ (self) : |
278 def __get__ (self) : |
237 return platform.ntohs(self.sockaddr.sin6_port) |
279 return platform.ntohs(self.sockaddr.sin6_port) |
238 |
280 |
239 |
281 |
|
282 property flowinfo : |
|
283 """ |
|
284 The integer flowinfo |
|
285 |
|
286 XXX: byteorder? |
|
287 """ |
|
288 |
|
289 def __get__ (self) : |
|
290 return self.sockaddr.sin6_flowinfo |
|
291 |
|
292 |
|
293 property scope_id : |
|
294 """ |
|
295 The scope ID - corresponds to an interface index for link-scope addresses. |
|
296 |
|
297 This should be in host byte order... |
|
298 """ |
|
299 |
|
300 def __get__ (self) : |
|
301 return self.sockaddr.sin6_scope_id |
|
302 |
|
303 def __cmp__ (self, other_obj) : |
|
304 """ |
|
305 A sockaddr_in6 is equal to any other sockaddr_in6 which has the same addr, port and scope ID. |
|
306 |
|
307 XXX: flowinfo? |
|
308 |
|
309 XXX: A sockaddr_in6 is also equal to a sockaddr_in if the sockaddr_in6 represents the given v4-mapped address. |
|
310 |
|
311 >>> assert sockaddr_in6() == sockaddr_in6() |
|
312 >>> assert sockaddr_in6('0:0:0::1', 80) == sockaddr_in6('::1', 80) |
|
313 >>> assert sockaddr_in6('::127.0.0.1') == sockaddr_in('127.0.0.1') |
|
314 """ |
|
315 |
|
316 if not isinstance(other_obj, sockaddr_in6) : |
|
317 return <object> py.Py_NotImplemented |
|
318 |
|
319 cdef sockaddr_in6 other = other_obj |
|
320 cdef platform.sockaddr_in6 *sa1 = &self.sockaddr, *sa2 = &other.sockaddr |
|
321 |
|
322 if other is self : |
|
323 return 0 |
|
324 |
|
325 return ( |
|
326 libc.memcmp(<void *> &sa1.sin6_port, <void *> &sa2.sin6_port, sizeof(sa1.sin6_port)) |
|
327 or libc.memcmp(<void *> &sa1.sin6_addr, <void *> &sa2.sin6_addr, sizeof(sa1.sin6_addr)) |
|
328 or libc.memcmp(<void *> &sa1.sin6_scope_id, <void *> &sa2.sin6_scope_id, sizeof(sa1.sin6_scope_id)) |
|
329 ) |
|
330 |
240 def __str__ (self) : |
331 def __str__ (self) : |
241 """ |
332 """ |
242 Return the literal ASCII representation for this sockaddr as a '[<addr>]:<port> string |
333 Return the literal ASCII representation for this sockaddr as a '[<addr>]:<port> string |
243 """ |
334 |
244 |
335 >>> str(sockaddr_in6()) |
245 # format |
336 '[::]:0' |
246 return "[%s]:%s" % self.getnameinfo() |
337 |
|
338 >>> str(sockaddr_in6('2001:0::05:1')) |
|
339 '[2001::5:1]' |
|
340 |
|
341 >>> str(sockaddr_in6('fe80::abcd', scope_id=5)) |
|
342 '[fe80::abcd%5]' |
|
343 """ |
|
344 |
|
345 addr, port = self.getnameinfo() |
|
346 scope_id = self.scope_id |
|
347 |
|
348 # format with scope_id |
|
349 return "[%s%s]:%s" % ( |
|
350 addr, |
|
351 "%%%d" % scope_id if scope_id else "", |
|
352 port |
|
353 ) |
247 |
354 |
248 # mapping of AF -> sockaddr, user-modifyable |
355 # mapping of AF -> sockaddr, user-modifyable |
249 SOCKADDR_BY_FAMILY = { |
356 SOCKADDR_BY_FAMILY = { |
250 platform.AF_INET: sockaddr_in, |
357 platform.AF_INET: sockaddr_in, |
251 platform.AF_INET6: sockaddr_in6, |
358 platform.AF_INET6: sockaddr_in6, |