[pypy-svn] r76951 - in pypy/branch/rsocket-improvements/pypy: module/_socket module/_socket/test rlib
fijal at codespeak.net
fijal at codespeak.net
Wed Sep 8 19:22:09 CEST 2010
Author: fijal
Date: Wed Sep 8 19:21:55 2010
New Revision: 76951
Modified:
pypy/branch/rsocket-improvements/pypy/module/_socket/interp_func.py
pypy/branch/rsocket-improvements/pypy/module/_socket/interp_socket.py
pypy/branch/rsocket-improvements/pypy/module/_socket/test/test_sock_app.py
pypy/branch/rsocket-improvements/pypy/rlib/_rsocket_rffi.py
pypy/branch/rsocket-improvements/pypy/rlib/rsocket.py
Log:
Implement AF_PACKET support. part 1 - interface name
Modified: pypy/branch/rsocket-improvements/pypy/module/_socket/interp_func.py
==============================================================================
--- pypy/branch/rsocket-improvements/pypy/module/_socket/interp_func.py (original)
+++ pypy/branch/rsocket-improvements/pypy/module/_socket/interp_func.py Wed Sep 8 19:21:55 2010
@@ -280,7 +280,7 @@
space.wrap(socktype),
space.wrap(protocol),
space.wrap(canonname),
- addr.as_object(space)])
+ addr.as_object(-1, space)]) # -1 as per cpython
for (family, socktype, protocol, canonname, addr) in lst]
return space.newlist(lst1)
getaddrinfo.unwrap_spec = [ObjSpace, W_Root, W_Root, int, int, int, int]
Modified: pypy/branch/rsocket-improvements/pypy/module/_socket/interp_socket.py
==============================================================================
--- pypy/branch/rsocket-improvements/pypy/module/_socket/interp_socket.py (original)
+++ pypy/branch/rsocket-improvements/pypy/module/_socket/interp_socket.py Wed Sep 8 19:21:55 2010
@@ -24,7 +24,7 @@
try:
sock, addr = self.accept(W_RSocket)
return space.newtuple([space.wrap(sock),
- addr.as_object(space)])
+ addr.as_object(sock.fd, space)])
except SocketError, e:
raise converted_error(space, e)
accept_w.unwrap_spec = ['self', ObjSpace]
@@ -109,7 +109,7 @@
"""
try:
addr = self.getpeername()
- return addr.as_object(space)
+ return addr.as_object(self.fd, space)
except SocketError, e:
raise converted_error(space, e)
getpeername_w.unwrap_spec = ['self', ObjSpace]
@@ -122,7 +122,7 @@
"""
try:
addr = self.getsockname()
- return addr.as_object(space)
+ return addr.as_object(self.fd, space)
except SocketError, e:
raise converted_error(space, e)
getsockname_w.unwrap_spec = ['self', ObjSpace]
@@ -202,7 +202,7 @@
try:
data, addr = self.recvfrom(buffersize, flags)
if addr:
- w_addr = addr.as_object(space)
+ w_addr = addr.as_object(self.fd, space)
else:
w_addr = space.w_None
return space.newtuple([space.wrap(data), w_addr])
@@ -330,7 +330,7 @@
try:
readlgt, addr = self.recvfrom_into(rwbuffer, nbytes, flags)
if addr:
- w_addr = addr.as_object(space)
+ w_addr = addr.as_object(self.fd, space)
else:
w_addr = space.w_None
return space.newtuple([space.wrap(readlgt), w_addr])
Modified: pypy/branch/rsocket-improvements/pypy/module/_socket/test/test_sock_app.py
==============================================================================
--- pypy/branch/rsocket-improvements/pypy/module/_socket/test/test_sock_app.py (original)
+++ pypy/branch/rsocket-improvements/pypy/module/_socket/test/test_sock_app.py Wed Sep 8 19:21:55 2010
@@ -2,6 +2,8 @@
import sys
import py
from pypy.tool.udir import udir
+from pypy.rlib import rsocket
+from pypy.rpython.lltypesystem import lltype, rffi
def setup_module(mod):
mod.space = gettestobjspace(usemodules=['_socket', 'array'])
@@ -221,21 +223,35 @@
"(_socket, host, port): return _socket.getaddrinfo(host, port)")
assert space.unwrap(w_l) == info
-def test_unknown_addr_as_object():
- from pypy.rlib import rsocket
- from pypy.rpython.lltypesystem import lltype, rffi
-
+def test_unknown_addr_as_object():
c_addr = lltype.malloc(rsocket._c.sockaddr, flavor='raw')
c_addr.c_sa_data[0] = 'c'
rffi.setintfield(c_addr, 'c_sa_family', 15)
# XXX what size to pass here? for the purpose of this test it has
# to be short enough so we have some data, 1 sounds good enough
# + sizeof USHORT
- w_obj = rsocket.Address(c_addr, 1 + 2).as_object(space)
+ w_obj = rsocket.Address(c_addr, 1 + 2).as_object(-1, space)
assert space.is_true(space.isinstance(w_obj, space.w_tuple))
assert space.int_w(space.getitem(w_obj, space.wrap(0))) == 15
assert space.str_w(space.getitem(w_obj, space.wrap(1))) == 'c'
+def test_addr_raw_packet():
+ if not hasattr(rsocket._c, 'sockaddr_ll'):
+ py.test.skip("posix specific test")
+ c_addr_ll = lltype.malloc(rsocket._c.sockaddr_ll, flavor='raw')
+ addrlen = rffi.sizeof(rsocket._c.sockaddr_ll)
+ c_addr = rffi.cast(lltype.Ptr(rsocket._c.sockaddr), c_addr_ll)
+ rffi.setintfield(c_addr_ll, 'c_sll_ifindex', 1)
+ rffi.setintfield(c_addr_ll, 'c_sll_protocol', 8)
+ rffi.setintfield(c_addr, 'c_sa_family', socket.AF_PACKET)
+ # fd needs to be somehow valid
+ s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ fd = s.fileno()
+ w_obj = rsocket.make_address(c_addr, addrlen).as_object(fd, space)
+ assert space.is_true(space.eq(w_obj, space.newtuple([
+ space.wrap('lo'),
+ space.w_None])))
+
def test_getnameinfo():
host = "127.0.0.1"
port = 25
Modified: pypy/branch/rsocket-improvements/pypy/rlib/_rsocket_rffi.py
==============================================================================
--- pypy/branch/rsocket-improvements/pypy/rlib/_rsocket_rffi.py (original)
+++ pypy/branch/rsocket-improvements/pypy/rlib/_rsocket_rffi.py Wed Sep 8 19:21:55 2010
@@ -32,6 +32,9 @@
'arpa/inet.h',
'stdint.h',
'errno.h',
+ 'netpacket/packet.h',
+ 'sys/ioctl.h',
+ 'net/if.h',
)
cond_includes = [('AF_NETLINK', 'linux/netlink.h')]
libraries = ()
@@ -190,6 +193,8 @@
FD_CONNECT_BIT FD_CLOSE_BIT
WSA_IO_PENDING WSA_IO_INCOMPLETE WSA_INVALID_HANDLE
WSA_INVALID_PARAMETER WSA_NOT_ENOUGH_MEMORY WSA_OPERATION_ABORTED
+
+SIOCGIFNAME
'''.split()
for name in constant_names:
@@ -309,6 +314,19 @@
[('fd', socketfd_type),
('events', rffi.SHORT),
('revents', rffi.SHORT)])
+
+ CConfig.sockaddr_ll = platform.Struct('struct sockaddr_ll',
+ [('sll_ifindex', rffi.INT),
+ ('sll_protocol', rffi.INT),
+ ('sll_pkttype', rffi.INT),
+ ('sll_hatype', rffi.INT),
+ ('sll_addr', rffi.CFixedArray(rffi.CHAR, 8)),
+ ('sll_halen', rffi.INT)],
+ )
+
+ CConfig.ifreq = platform.Struct('struct ifreq', [('ifr_ifindex', rffi.INT),
+ ('ifr_name', rffi.CFixedArray(rffi.CHAR, 8))])
+
if _WIN32:
CConfig.WSAEVENT = platform.SimpleType('WSAEVENT', rffi.VOIDP)
CConfig.WSANETWORKEVENTS = platform.Struct(
@@ -408,6 +426,8 @@
if _POSIX:
nfds_t = cConfig.nfds_t
pollfd = cConfig.pollfd
+ sockaddr_ll = cConfig.sockaddr_ll
+ ifreq = cConfig.ifreq
if WIN32:
WSAEVENT = cConfig.WSAEVENT
WSANETWORKEVENTS = cConfig.WSANETWORKEVENTS
@@ -510,6 +530,8 @@
socketpair_t = rffi.CArray(socketfd_type)
socketpair = external('socketpair', [rffi.INT, rffi.INT, rffi.INT,
lltype.Ptr(socketpair_t)], rffi.INT)
+ ioctl = external('ioctl', [socketfd_type, rffi.INT, lltype.Ptr(ifreq)],
+ rffi.INT)
if _WIN32:
ioctlsocket = external('ioctlsocket',
Modified: pypy/branch/rsocket-improvements/pypy/rlib/rsocket.py
==============================================================================
--- pypy/branch/rsocket-improvements/pypy/rlib/rsocket.py (original)
+++ pypy/branch/rsocket-improvements/pypy/rlib/rsocket.py Wed Sep 8 19:21:55 2010
@@ -6,8 +6,7 @@
# Known missing features:
#
-# - support for non-Linux platforms
-# - address families other than AF_INET, AF_INET6, AF_UNIX
+# - address families other than AF_INET, AF_INET6, AF_UNIX, AF_PACKET
# - methods makefile(),
# - SSL
#
@@ -109,7 +108,7 @@
"""
keepalive_until_here(self)
- def as_object(self, space):
+ def as_object(self, fd, space):
"""Convert the address to an app-level object."""
# If we don't know the address family, don't raise an
# exception -- return it as a tuple.
@@ -200,6 +199,31 @@
# ____________________________________________________________
+class PacketAddress(Address):
+ family = AF_PACKET
+ struct = _c.sockaddr_ll
+ maxlen = minlen = sizeof(struct)
+
+ def get_ifname(self, fd):
+ a = self.lock(_c.sockaddr_ll)
+ p = lltype.malloc(_c.ifreq, flavor='raw')
+ rffi.setintfield(p, 'c_ifr_ifindex',
+ rffi.getintfield(a, 'c_sll_ifindex'))
+ if (_c.ioctl(fd, _c.SIOCGIFNAME, p) == 0):
+ ifname = rffi.charp2str(p.c_ifr_name)
+ else:
+ ifname = ""
+ lltype.free(p, flavor='raw')
+ self.unlock()
+ return ifname
+
+ def get_protocol(self):
+ a = self.lock
+
+ def as_object(self, fd, space):
+ return space.newtuple([space.wrap(self.get_ifname(fd)),
+ space.wrap(self.get_protocol())])
+
class INETAddress(IPAddress):
family = AF_INET
struct = _c.sockaddr_in
@@ -228,7 +252,7 @@
self.get_host() == other.get_host() and
self.get_port() == other.get_port())
- def as_object(self, space):
+ def as_object(self, fd, space):
return space.newtuple([space.wrap(self.get_host()),
space.wrap(self.get_port())])
@@ -317,7 +341,7 @@
self.get_flowinfo() == other.get_flowinfo() and
self.get_scope_id() == other.get_scope_id())
- def as_object(self, space):
+ def as_object(self, fd, space):
return space.newtuple([space.wrap(self.get_host()),
space.wrap(self.get_port()),
space.wrap(self.get_flowinfo()),
@@ -421,7 +445,7 @@
return (isinstance(other, UNIXAddress) and
self.get_path() == other.get_path())
- def as_object(self, space):
+ def as_object(self, fd, space):
return space.wrap(self.get_path())
def from_object(space, w_address):
@@ -456,7 +480,7 @@
def __repr__(self):
return '<NETLINKAddress %r>' % (self.get_pid(), self.get_groups())
- def as_object(self, space):
+ def as_object(self, fd, space):
return space.newtuple([space.wrap(self.get_pid()),
space.wrap(self.get_groups())])
@@ -613,7 +637,7 @@
# convert an Address into an app-level object
def addr_as_object(self, space, address):
- return address.as_object(space)
+ return address.as_object(self.fd, space)
# convert an app-level object into an Address
# based on the current socket's family
More information about the Pypy-commit
mailing list