Skip to content

Userspace TUN for RSD #1409

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft

Conversation

strobecat
Copy link

@strobecat strobecat commented Jun 8, 2025

This PR wants to add a userspace TUN to connect to RSD service.

I've tested that pymobiledevice3 developer dvt ls / --userspace-wrapper ... --rsd ... with pymobiledevice3 lockdown start-tunnel --userspace-host 0.0.0.0 works on iPadOS 18.5 and Python 3.10.12. Tunneld current not ported

Source of swtcp6_pmd3 is here: strobecat/swtcp6-pmd3 (I assume Apple only use ipv6 for RSD)
the packages serve as a virtual NIC and TCP FSMs, process (everytime .poll() got called) raw IPv6 bytes from device, update TCP FSM, and send raw bytes to the device.
Closes #1260

For community

⬇️ Please click the 👍 reaction instead of leaving a +1 or 👍 comment

@strobecat strobecat force-pushed the dev/userspace_tun branch from 6bd8922 to 48ce9e1 Compare June 8, 2025 13:07
@@ -139,14 +142,16 @@
class RemotePairingTunnel(ABC):
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Abstracted RemotePairingTunnel, OSRemotePairingTunnel => Use OS TUN interface (pytun_pmd3), UserspacePairingTunnel => Use userspace TCP/IPv6 stack (swtcp6_pmd3)

@staticmethod
def _encode_cdtunnel_packet(data: dict) -> bytes:
return CDTunnelPacket.build({'body': json.dumps(data).encode()})

Copy link
Author

@strobecat strobecat Jun 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Works as the same way of go-ios: create a tcp server at _userspace_host:random_port
When connecting to a RSD service:

  • intf_poll_task sync raw IPv6 data between idevice and virtual NIC
  • Client (see ServiceConnection) connect to the userspace wrapper tcp server
  • Send address and port of RSD service (dest) => server tries to connect dest via virtual NIC
  • Server sync all data sent by client to dest

try:
yield TunnelResult(
client.tun.name, handshake_response['serverAddress'], handshake_response['serverRSDPort'],
client.get_interface(), handshake_response['serverAddress'], handshake_response['serverRSDPort'],
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.get_interface will be '<userspace TUN server host> <port>' if isinstance(client, UserspaceRemotePairingTunnel)

if script_mode:
print(f'{tunnel_result.address} {tunnel_result.port}')
if userspace_host:
print(f'{tunnel_result.address} {tunnel_result.port} {tunnel_result.interface}')
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here tunnel_result.interface is '<host> <port>' of Userspace TUN server if use_userspace

self._run_coroutine(self.send_packet_to_device(packet))

@asyncio_print_traceback
async def intf_poll_task(self) -> None:
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

poll means let virtual NIC process all incoming raw IPv6 bytes (from a buffer), outgoing traffic (to a buffer)
after poll, outgoing buffer would be some data so send it to device

await self._polled.wait()
to_send = await r.read(available_buf)
if not to_send:
# connection lost
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

connect between ServiceConnection and the function lost

@doronz88
Copy link
Owner

doronz88 commented Jun 8, 2025

How to run the userspace tunnel? will it be its own pypi package?

@strobecat strobecat force-pushed the dev/userspace_tun branch from 48ce9e1 to 3194a12 Compare June 10, 2025 14:51
@strobecat
Copy link
Author

By normal way you start tunnel but with a --userspace-host paramater, e.g. pymobiledevice3 lockdown start-tunnel --userspace-host 127.0.0.1
Maybe swtcp6_pmd3 will be packaged seperately like pytun_pmd3?

@doronz88
Copy link
Owner

I failed to figure out how to use swtcp6-pmd3. It should have a proper README and uploaded to pypi. Doesn't seem to contain any CLI for bringing up the server you mentioned

@strobecat
Copy link
Author

strobecat commented Jun 11, 2025

Ah sorry sir I forget to mention that. It was used as a library in pymobiledevice3/remote/tunnel_service.py; it can be installed by pip install git+https://github.com/strobecat/swtcp6-pmd3 (requires rust toolchain) or wheel from actions, as it's currently in dev state

@doronz88
Copy link
Owner

I see. This means this dependency needs to be either optional or be compiled cross platforms using cibuildwheel to be included

@strobecat strobecat force-pushed the dev/userspace_tun branch 2 times, most recently from 55dc986 to 33239d2 Compare June 15, 2025 07:45
@strobecat strobecat force-pushed the dev/userspace_tun branch 2 times, most recently from 4d271b1 to 945cfa1 Compare June 15, 2025 16:23
Repository owner deleted a comment Jun 15, 2025
Repository owner deleted a comment Jun 15, 2025
@strobecat strobecat force-pushed the dev/userspace_tun branch from 945cfa1 to 0a9c2c6 Compare June 16, 2025 14:02
@strobecat
Copy link
Author

strobecat commented Jun 17, 2025

Userspace TUN
OS Tun
Brief description about how OSRemotePairingTunnel and UserspaceRemotePairingTunnel works

@strobecat strobecat force-pushed the dev/userspace_tun branch from 0a9c2c6 to dcfca88 Compare June 18, 2025 01:43
@leaflinfeng
Copy link

@strobecat can the rsd which started in this way be used to start debug server ?

@strobecat
Copy link
Author

strobecat commented Aug 6, 2025

@strobecat can the rsd which started in this way be used to start debug server ?

it should function like system tun ideally

btw pr progress: I'm currently try to give swtcp6-pmd4 a asyncio.transport-like interface, but delayed a bit due to some rust troubles, so this pr is kind of stall

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

FEATURE REQUEST: Implementing Tunnel Creation without sudo
3 participants