Ejemplo n.º 1
0
 async def make(cls, parent: Process, addr: ipaddress.IPv4Address,
                peer: ipaddress.IPv4Address) -> 'Tun':
     # put each tun in a separate netns; I tried putting them in
     # the same netns, but got silent packet delivery failures.
     process = await parent.clone(CLONE.NEWNET | CLONE.FILES)
     self = cls(
         process,
         await process.task.open(await process.ptr("/dev/net/tun"), O.RDWR),
         'tun0',
         addr,
         await process.task.socket(AF.INET, SOCK.STREAM),
     )
     await self.fd.ioctl(
         TUNSETIFF, await
         self.process.ptr(Ifreq(self.name, flags=IFF.TUN | IFF.NO_PI)))
     # set up the tun - these ioctls don't actually affect the socket
     await self.sock.ioctl(
         SIOC.SIFFLAGS, await
         self.process.ptr(Ifreq(self.name, flags=IFF.UP)))
     await self.sock.ioctl(
         SIOC.SIFADDR, await
         self.process.ptr(Ifreq(self.name, addr=SockaddrIn(0, self.addr))))
     await self.sock.ioctl(
         SIOC.SIFDSTADDR, await
         self.process.ptr(Ifreq(self.name, addr=SockaddrIn(0, peer))))
     await self.sock.bind(await
                          self.process.ptr(SockaddrIn(1234, self.addr)))
     return self
Ejemplo n.º 2
0
    async def test_dgram(self) -> None:
        "With DGRAM sockets, without SO.REUSEADDR, binding 0 twice will never give you the same port."
        sockfd = await self.process.task.socket(AF.INET, SOCK.DGRAM)
        await sockfd.bind(await
                          self.process.task.ptr(SockaddrIn(0, '127.0.0.1')))

        sockfd2 = await self.process.task.socket(AF.INET, SOCK.DGRAM)
        with self.assertRaises(OSError) as cm:
            await sockfd2.bind(await self.process.task.ptr(
                SockaddrIn(0, '127.0.0.1')))
        self.assertEqual(cm.exception.errno, errno.EADDRINUSE)
Ejemplo n.º 3
0
    async def test_stream_reuseaddr(self) -> None:
        "With STREAM sockets, even if you use SO.REUSEADDR, binding 0 twice will never give you the same port."
        sockfd = await self.process.task.socket(AF.INET, SOCK.STREAM)
        await sockfd.setsockopt(SOL.SOCKET, SO.REUSEADDR, await
                                self.process.ptr(Int32(1)))
        await sockfd.bind(await
                          self.process.task.ptr(SockaddrIn(0, '127.0.0.1')))

        sockfd2 = await self.process.task.socket(AF.INET, SOCK.STREAM)
        await sockfd2.setsockopt(SOL.SOCKET, SO.REUSEADDR, await
                                 self.process.ptr(Int32(1)))
        with self.assertRaises(OSError) as cm:
            await sockfd2.bind(await self.process.task.ptr(
                SockaddrIn(0, '127.0.0.1')))
        self.assertEqual(cm.exception.errno, errno.EADDRINUSE)
Ejemplo n.º 4
0
    async def test_reuseaddr_listen(self) -> None:
        """If you use SO.REUSEADDR, your local and peer address can be the same

        This is kind of alarming and surprising, but it's a real behavior.
        """
        sockfd = await self.process.task.socket(AF.INET, SOCK.STREAM)
        await sockfd.setsockopt(SOL.SOCKET, SO.REUSEADDR, await
                                self.process.ptr(Int32(1)))
        addr = await self.process.bind_getsockname(sockfd,
                                                   SockaddrIn(0, '127.0.0.1'))

        sockfd2 = await self.process.task.socket(AF.INET, SOCK.STREAM)
        await sockfd2.setsockopt(SOL.SOCKET, SO.REUSEADDR, await
                                 self.process.ptr(Int32(1)))
        await sockfd2.bind(await self.process.ptr(addr))
        await sockfd.listen(10)

        await sockfd2.connect(await self.process.ptr(addr))

        sockbuf_ptr = await sockfd2.getsockname(await self.process.ptr(
            Sockbuf(await self.process.malloc(SockaddrIn))))
        self.assertEqual(addr, await (await sockbuf_ptr.read()).buf.read())
        sockbuf_ptr = await sockfd2.getpeername(await self.process.ptr(
            Sockbuf(await self.process.malloc(SockaddrIn))))
        self.assertEqual(addr, await (await sockbuf_ptr.read()).buf.read())
Ejemplo n.º 5
0
 def test_ifreq(self) -> None:
     initial = Ifreq()
     initial.name = "hello"
     initial.addr = SockaddrIn(42, "127.0.0.1")
     output = Ifreq.from_bytes(initial.to_bytes())
     self.assertEqual(initial.name, output.name)
     self.assertEqual(initial.addr.port, output.addr.port)
     self.assertEqual(initial.addr.addr, output.addr.addr)
Ejemplo n.º 6
0
    async def test_dgram_reuseaddr(self) -> None:
        """With DGRAM sockets, if you use SO.REUSEADDR, binding 0 *can* give you the same port.

        But note that you can also just set REUSEADDR after binding.
        """
        sockfd = await self.process.task.socket(AF.INET, SOCK.DGRAM)
        await sockfd.setsockopt(SOL.SOCKET, SO.REUSEADDR, await
                                self.process.ptr(Int32(1)))
        addr = await self.process.bind_getsockname(sockfd,
                                                   SockaddrIn(0, '127.0.0.1'))

        sockfd2 = await self.process.task.socket(AF.INET, SOCK.DGRAM)
        await sockfd2.setsockopt(SOL.SOCKET, SO.REUSEADDR, await
                                 self.process.ptr(Int32(1)))
        addr2 = await self.process.bind_getsockname(sockfd2,
                                                    SockaddrIn(0, '127.0.0.1'))

        self.assertEqual(addr, addr2)
Ejemplo n.º 7
0
 def test_ifreq(self) -> None:
     initial = Ifreq()
     initial.name = "hello"
     initial.addr = SockaddrIn(42, "127.0.0.1")
     output = Ifreq.from_bytes(initial.to_bytes())
     self.assertEqual(initial.name, output.name)
     addr = t.cast(SockaddrIn, initial.addr.parse())
     self.assertIsInstance(addr, SockaddrIn)
     self.assertEqual(initial.addr.port, addr.port)
     self.assertEqual(initial.addr.addr, addr.addr)
Ejemplo n.º 8
0
 async def test_ioctl(self) -> None:
     await self.process.unshare(CLONE.NEWNET)
     tun_fd = await self.process.task.open(
         await self.process.ram.ptr("/dev/net/tun"), O.RDWR)
     name = 'tun0'
     ptr = await self.process.ram.ptr(Ifreq(name, flags=IFF.TUN))
     await tun_fd.ioctl(TUNSETIFF, ptr)
     sock = await self.process.task.socket(AF.INET, SOCK.STREAM)
     await sock.ioctl(SIOC.GIFINDEX, ptr)
     # this is the second interface in an empty netns
     self.assertEqual((await ptr.read()).ifindex, 2)
     # set it up
     ptr = await ptr.write(Ifreq(name, flags=IFF.UP))
     await sock.ioctl(SIOC.SIFFLAGS, ptr)
     await sock.ioctl(SIOC.GIFFLAGS, ptr)
     self.assertIn(IFF.UP, (await ptr.read()).flags)  # type: ignore
     # add IP address
     addr = SockaddrIn(0, '10.0.0.1')
     ptr = await ptr.write(Ifreq(name, addr=addr))
     await sock.ioctl(SIOC.SIFADDR, ptr)
     await sock.ioctl(SIOC.GIFADDR, ptr)
     self.assertEqual(addr, (await ptr.read()).addr.parse())
Ejemplo n.º 9
0
 def __set__(self, instance, value: SockaddrIn) -> None:
     data_bytes = value.to_bytes()
     ffi.memmove(ffi.addressof(instance.cffi, self.name),
                 ffi.from_buffer(data_bytes), len(data_bytes))
Ejemplo n.º 10
0
 def __get__(self, instance, owner) -> SockaddrIn:
     data_bytes = bytes(ffi.buffer(ffi.addressof(instance.cffi, self.name)))
     return SockaddrIn.from_bytes(data_bytes)
Ejemplo n.º 11
0
 async def do_conn():
     await conn.sock.connect(await conn.process.ptr(
         SockaddrIn(1234, acc.addr)))