1
1
import time
2
2
import socket
3
- import threading
3
+ import select
4
+ import uuid
5
+
6
+ from .ts3client import Ts3Client
7
+
8
+ """tcp relay class
9
+
10
+ class for relaying the teamspeak3 tcp communication stuff
11
+ """
4
12
5
13
6
14
class Tcp ():
@@ -12,65 +20,45 @@ def __init__(self, relayPort, remoteAddr, remotePort):
12
20
self .socket .listen ()
13
21
self .remoteAddr = remoteAddr
14
22
self .remotePort = remotePort
15
- self .clientList = dict ()
16
- t = threading .Thread (target = self .get_from_server )
17
- t .start ()
18
-
19
- def get_from_server (self ):
20
- while True :
21
- # send data from remote server to specific client
22
- for key in list (self .clientList ):
23
- try :
24
- data = self .clientList [key ]['rsocket' ].recv (1024 )
25
- self .clientList [key ]['lastseen' ] = time .time ()
26
- self .clientList [key ]['csocket' ].send (data )
27
- except socket .error as msg :
28
- pass
29
- time .sleep (.025 )
30
-
31
- def get_from_client (self , conn , addr ):
32
- while True :
33
- try :
34
- # if we see the client the first time
35
- if not addr in self .clientList :
36
- print ('connected: ' + str (addr ))
37
- rsocket = socket .socket (socket .AF_INET , socket .SOCK_STREAM )
38
- rsocket .connect ((self .remoteAddr , self .remotePort ))
39
- rsocket .setblocking (False )
40
- self .clientList [addr ] = {
41
- 'rsocket' : rsocket ,
42
- 'csocket' : conn ,
43
- 'lastseen' : time .time ()
44
- }
45
- data = conn .recv (1024 )
46
- if len (data ) != 0 :
47
- self .clientList [addr ]['rsocket' ].send (data )
48
- else :
49
- self .clientList [addr ]['rsocket' ].close ()
50
- del self .clientList [addr ]
51
- print ('disconnected: ' + str (addr ))
52
- break
53
- except :
54
- try :
55
- self .clientList [addr ]['rsocket' ].close ()
56
- except :
57
- pass
58
- try :
59
- self .clientList [addr ]['csocket' ].close ()
60
- except :
61
- pass
62
- del self .clientList [addr ]
63
- print ('disconnected: ' + str (addr ))
64
- break
65
- time .sleep (.025 )
23
+ self .clients = {}
66
24
67
25
def relay (self ):
68
26
while True :
69
- # get data from an connected client
70
- conn , addr = self .socket .accept ()
71
- try :
72
- t = threading .Thread (
73
- target = self .get_from_client , args = (conn , addr ))
74
- t .start ()
75
- except :
76
- pass
27
+ readable , writable , exceptional = select .select (list (self .clients .values ()) + [self .socket ], [], [], 1 )
28
+ for s in readable :
29
+ # if ts3 server answers to a client or vice versa
30
+ if isinstance (s , Ts3Client ):
31
+ try :
32
+ data = s .socket .recv (4096 )
33
+ if len (data ) != 0 :
34
+ self .clients [s .addr ].socket .send (data )
35
+ else :
36
+ raise
37
+ except :
38
+ # get second socket from list
39
+ addr = self .clients [s .addr ].addr
40
+ try :
41
+ # close other socket
42
+ self .clients [s .addr ].socket .close ()
43
+ except :
44
+ pass
45
+ try :
46
+ # close own socket, too
47
+ self .clients [addr ].socket .close ()
48
+ except :
49
+ pass
50
+ del self .clients [s .addr ]
51
+ del self .clients [addr ]
52
+ if isinstance (addr , tuple ):
53
+ print ('disconnected' , addr )
54
+ else :
55
+ print ('disconnected' , s .addr )
56
+ else :
57
+ conn , addr = s .accept ()
58
+ data = conn .recv (4096 )
59
+ print ('connected' , addr )
60
+ tmpuid = str (uuid .uuid4 ())
61
+ self .clients [addr ] = Ts3Client (conn , tmpuid )
62
+ self .clients [tmpuid ] = Ts3Client (socket .socket (socket .AF_INET , socket .SOCK_STREAM ), addr )
63
+ self .clients [tmpuid ].socket .connect ((self .remoteAddr , self .remotePort ))
64
+ self .clients [tmpuid ].socket .send (data )
0 commit comments