File: _socket_proxy.py

package info (click to toggle)
oscrypto 1.3.0-7
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,164 kB
  • sloc: python: 22,115; makefile: 7
file content (68 lines) | stat: -rw-r--r-- 1,973 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# coding: utf-8
from __future__ import unicode_literals, division, absolute_import, print_function


import socket
import select
import threading


_sockets = {}
_socket_lock = threading.Lock()


def proxy(src, dst, callback=None):
    timeout = 10
    try:
        read_ready, _, _ = select.select([src], [], [], timeout)
        while len(read_ready):
            if callback:
                callback(src, dst)
            else:
                dst.send(src.recv(8192))
            read_ready, _, _ = select.select([src], [], [], timeout)
    except (socket.error, select.error, OSError, ValueError):
        pass
    try:
        src.shutdown(socket.SHUT_RDWR)
    except (socket.error, OSError, ValueError):
        pass
    src.close()
    try:
        dst.shutdown(socket.SHUT_RDWR)
    except (socket.error, OSError, ValueError):
        pass
    dst.close()


def listen(server, ip, port, send_callback, recv_callback):
    lsock, laddr = server.accept()
    rsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    rsock.connect((ip, port))
    with _socket_lock:
        _sockets[threading.current_thread().ident] = {
            'lsock': lsock,
            'rsock': rsock
        }
    t1 = threading.Thread(target=proxy, args=(rsock, lsock, recv_callback))
    t2 = threading.Thread(target=proxy, args=(lsock, rsock, send_callback))
    t1.start()
    t2.start()


def make_socket_proxy(ip, port, send_callback=None, recv_callback=None):
    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    server.bind(('', 8080))
    server.listen(1)
    t = threading.Thread(
        target=listen,
        args=(server, ip, port, send_callback, recv_callback)
    )
    t.start()
    sock = socket.create_connection(('localhost', 8080))
    sock.settimeout(1)
    t.join()
    with _socket_lock:
        data = _sockets[t.ident]
        return (sock, data['lsock'], data['rsock'], server)