Readit News logoReadit News

Deleted Comment

fiddyschmitt commented on Show HN: Tunnelling TCP through a file   github.com/fiddyschmitt/F... · Posted by u/fiddyschmitt
DonHopkins · 2 years ago
Will this work with a pigeon and a USB stick? (Given a pigeon strong and fast enough to fly back and forth thousands of times.)
fiddyschmitt · 2 years ago
Haha!
fiddyschmitt commented on Show HN: Tunnelling TCP through a file   github.com/fiddyschmitt/F... · Posted by u/fiddyschmitt
jclarkcom · 2 years ago
I think you can use named pipes if you are using SMB. Here is a example code in python (not tested).

import socket import win32pipe import win32file import sys

BUFFER_SIZE = 4096

def create_pipe(pipe_name): return win32pipe.CreateNamedPipe(pipe_name, win32pipe.PIPE_ACCESS_DUPLEX, win32pipe.PIPE_TYPE_BYTE | win32pipe.PIPE_READMODE_BYTE | win32pipe.PIPE_WAIT, 1, BUFFER_SIZE, BUFFER_SIZE, 0, None)

def open_pipe(pipe_name): return win32file.CreateFile(pipe_name, win32file.GENERIC_READ | win32file.GENERIC_WRITE, 0, None, win32file.OPEN_EXISTING, 0, None)

def proxy_server(machine_name): server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_socket.bind(('0.0.0.0', 8080)) server_socket.listen(1)

    pipe_name_1 = r'\\' + machine_name + r'\pipe\proxy_pipe_1'
    pipe_name_2 = r'\\' + machine_name + r'\pipe\proxy_pipe_2'

    while True:
        client_socket, _ = server_socket.accept()
        pipe_1, pipe_2 = create_pipe(pipe_name_1), create_pipe(pipe_name_2)
        win32pipe.ConnectNamedPipe(pipe_1, None)
        win32pipe.ConnectNamedPipe(pipe_2, None)

        while True:
            data = client_socket.recv(BUFFER_SIZE)
            if not data:
                break
            win32file.WriteFile(pipe_1, data)
            response = win32file.ReadFile(pipe_2, BUFFER_SIZE)[1]
            client_socket.send(response)

        client_socket.close()
        win32file.CloseHandle(pipe_1)
        win32file.CloseHandle(pipe_2)
def proxy_client(server_name, machine_name): target_host, target_port = 'cnn.com', 80

    pipe_name_1 = r'\\' + server_name + r'\pipe\proxy_pipe_1_' + machine_name
    pipe_name_2 = r'\\' + server_name + r'\pipe\proxy_pipe_2_' + machine_name

    pipe_1, pipe_2 = open_pipe(pipe_name_1), open_pipe(pipe_name_2)
    target_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    target_socket.connect((target_host, target_port))

    while True:
        data = win32file.ReadFile(pipe_1, BUFFER_SIZE)[1]
        if not data:
            break
        target_socket.send(data)
        response = target_socket.recv(BUFFER_SIZE)
        win32file.WriteFile(pipe_2, response)

    target_socket.close()
    win32file.CloseHandle(pipe_1)
    win32file.CloseHandle(pipe_2)
if __name__ == '__main__': if len(sys.argv) < 3: print("Usage: python script.py [server|client] [machine_name] [server_name (for client only)]") sys.exit(1)

    mode, machine_name = sys.argv[1], sys.argv[2]

    if mode == 'server':
        proxy_server(machine_name)
    elif mode == 'client':
        if len(sys.argv) < 4:
            print("Please provide the server name or IP address for the client mode.")
            sys.exit(1)
        server_name = sys.argv[3]
        proxy_client(server_name, machine_name)
    else:
        print("Invalid mode. Please use 'server' or 'client'.")
        sys.exit(1)

fiddyschmitt · 2 years ago
That's awesome!
fiddyschmitt commented on Show HN: Tunnelling TCP through a file   github.com/fiddyschmitt/F... · Posted by u/fiddyschmitt
resoluteteeth · 2 years ago
For RDP you can use virtual channels so you don't need to use a file over drive redirection
fiddyschmitt · 2 years ago
Cool. I think rdp2tcp uses virtual channels for tunneling:

https://rdp2tcp.sourceforge.net/

fiddyschmitt commented on Show HN: Tunnelling TCP through a file   github.com/fiddyschmitt/F... · Posted by u/fiddyschmitt
rakoo · 2 years ago
There's a more complete version of this with nncp: https://www.complete.org/nncp/
fiddyschmitt · 2 years ago
Woah!
fiddyschmitt commented on Show HN: Tunnelling TCP through a file   github.com/fiddyschmitt/F... · Posted by u/fiddyschmitt
jandrese · 2 years ago
It looks like one file per direction, and this is a point to point connection. It looks like each side just reads to the end of the file and then tries to read more to see if any new data is available.
fiddyschmitt · 2 years ago
Yes exactly. One file in each direction made arbitration easier.

In the future I will implement a single file to handle both directions.

fiddyschmitt commented on Show HN: Tunnelling TCP through a file   github.com/fiddyschmitt/F... · Posted by u/fiddyschmitt
andrewstuart · 2 years ago
So there’s multiple writers to the file? How is this arbitrated?

Also how does either side know when the file has been updated?

fiddyschmitt · 2 years ago
Hi Andrew, there's just one writer (which can tunnel multiple TCP connections).

Arbitration was indeed one of the trickiest bits. Originally I pre-reallocated the full file size (10 MB). Then used an integer at the beginning of the file to signal to the other side that a block was ready. The other side repeatedly read that int, and read the corresponding part of the file. But writing twice (once for the data, once for the int) had a significant performance impact.

In the end, what worked best was not pre-allocating the file. Rather letting the file grow whenever the writer writes to it. The reader knows when data is available by doing a PeekChar() in a tight loop. It's surprisingly fast, and accurately reflects the state of the file.

fiddyschmitt commented on Show HN: Tunnelling TCP through a file   github.com/fiddyschmitt/F... · Posted by u/fiddyschmitt
bawolff · 2 years ago
What's the benefit of this over netcat + mkfifo?
fiddyschmitt · 2 years ago
Hi Bawolff! Yes that's a great combo. I guess File Tunnel provides a couple of things that makes the tunnel maintenance a bit easier.

1. It gracefully supports each side of the tunnel turning on and off.

2. It accepts any number of clients, and forwards them through the tunnel.

3. It recycles the shared file.

fiddyschmitt commented on Show HN: Tunnelling TCP through a file   github.com/fiddyschmitt/F... · Posted by u/fiddyschmitt
jclarkcom · 2 years ago
Neat idea. For better performance, you might want to use native filesystem APIs, for example on windows use CreateFile with the FILE_WRITE_THROUGH flag to prevent caching and and extra flushing.
fiddyschmitt · 2 years ago
Thanks J :) Absolutely! I did try various flags to optimise performance. For CreateFile (which in .NET is wrapped by the FileStream class) I tried FILE_WRITE_THROUGH (which is FileOptions.WriteThrough in .NET), and found it impacted performance quite a lot.

The key to high performance as you rightly pointed out was preventing flushing. In the end, what worked best was reducing the number of writes to disk (which is the bottleneck). I did that by buffering 10-50 ms worth of TCP data, coupled with only flushing explicitly (using a large buffer so that neither BinaryWriter or FileStream flush automatically).

u/fiddyschmitt

KarmaCake day253April 13, 2016View Original