def __wait_windows(self, poller, wait): if self.socket is not None: if wait == Stream.W_RECV: read_flags = (win32file.FD_READ | win32file.FD_ACCEPT | win32file.FD_CLOSE) try: win32file.WSAEventSelect(self.socket, self._read.hEvent, read_flags) except pywintypes.error as e: vlog.err("failed to associate events with socket: %s" % e.strerror) poller.fd_wait(self._read.hEvent, ovs.poller.POLLIN) else: write_flags = (win32file.FD_WRITE | win32file.FD_CONNECT | win32file.FD_CLOSE) try: win32file.WSAEventSelect(self.socket, self._write.hEvent, write_flags) except pywintypes.error as e: vlog.err("failed to associate events with socket: %s" % e.strerror) poller.fd_wait(self._write.hEvent, ovs.poller.POLLOUT) else: if wait == Stream.W_RECV: if self._read: poller.fd_wait(self._read.hEvent, ovs.poller.POLLIN) elif wait == Stream.W_SEND: if self._write: poller.fd_wait(self._write.hEvent, ovs.poller.POLLOUT) elif wait == Stream.W_CONNECT: return
def test_functional(self): # This is not really a unit test, but it does exercise the code # quite well and can serve as an example of WSAEventSelect and # WSAEnumNetworkEvents usage. port = socket.socket() port.setblocking(0) port_event = win32event.CreateEvent(None, 0, 0, None) win32file.WSAEventSelect(port, port_event, win32file.FD_ACCEPT | win32file.FD_CLOSE) port.bind(("127.0.0.1", 0)) port.listen(10) client = socket.socket() client.setblocking(0) client_event = win32event.CreateEvent(None, 0, 0, None) win32file.WSAEventSelect(client, client_event, win32file.FD_CONNECT | win32file.FD_READ | win32file.FD_WRITE | win32file.FD_CLOSE) err = client.connect_ex(port.getsockname()) self.assertEquals(err, win32file.WSAEWOULDBLOCK) res = win32event.WaitForSingleObject(port_event, 1000) self.assertEquals(res, win32event.WAIT_OBJECT_0) events = win32file.WSAEnumNetworkEvents(port, port_event) self.assertEquals(events, {win32file.FD_ACCEPT: 0}) server, addr = port.accept() server.setblocking(0) server_event = win32event.CreateEvent(None, 1, 0, None) win32file.WSAEventSelect(server, server_event, win32file.FD_READ | win32file.FD_WRITE | win32file.FD_CLOSE) res = win32event.WaitForSingleObject(server_event, 1000) self.assertEquals(res, win32event.WAIT_OBJECT_0) events = win32file.WSAEnumNetworkEvents(server, server_event) self.assertEquals(events, {win32file.FD_WRITE: 0}) res = win32event.WaitForSingleObject(client_event, 1000) self.assertEquals(res, win32event.WAIT_OBJECT_0) events = win32file.WSAEnumNetworkEvents(client, client_event) self.assertEquals(events, {win32file.FD_CONNECT: 0, win32file.FD_WRITE: 0}) sent = 0 data = str2bytes("x") * 16 * 1024 while sent < 16 * 1024 * 1024: try: sent += client.send(data) except socket.error, e: if e.args[0] == win32file.WSAEINTR: continue elif e.args[0] in (win32file.WSAEWOULDBLOCK, win32file.WSAENOBUFS): break else: raise
def test_basics(self): s = socket.socket() e = win32event.CreateEvent(None, 1, 0, None) win32file.WSAEventSelect(s, e, 0) self.assertEquals(win32file.WSAEnumNetworkEvents(s), {}) self.assertEquals(win32file.WSAEnumNetworkEvents(s, e), {}) self.assertRaises(TypeError, win32file.WSAEnumNetworkEvents, s, e, 3) self.assertRaises(TypeError, win32file.WSAEnumNetworkEvents, s, "spam") self.assertRaises(TypeError, win32file.WSAEnumNetworkEvents, "spam", e) self.assertRaises(TypeError, win32file.WSAEnumNetworkEvents, "spam") f = open("NUL") h = win32file._get_osfhandle(f.fileno()) self.assertRaises(win32file.error, win32file.WSAEnumNetworkEvents, h) self.assertRaises(win32file.error, win32file.WSAEnumNetworkEvents, s, h) try: win32file.WSAEnumNetworkEvents(h) except win32file.error as e: self.assertEquals(e.winerror, win32file.WSAENOTSOCK) try: win32file.WSAEnumNetworkEvents(s, h) except win32file.error as e: # According to the docs it would seem reasonable that # this would fail with WSAEINVAL, but it doesn't. self.assertEquals(e.winerror, win32file.WSAENOTSOCK)
def check_connection_completion(sock): if sys.platform == "win32": p = ovs.poller.SelectPoll() event = winutils.get_new_event(None, False, True, None) # Receive notification of readiness for writing, of completed # connection or multipoint join operation, and of socket closure. win32file.WSAEventSelect(sock, event, win32file.FD_WRITE | win32file.FD_CONNECT | win32file.FD_CLOSE) p.register(event, ovs.poller.POLLOUT) else: p = ovs.poller.get_system_poll() p.register(sock, ovs.poller.POLLOUT) pfds = p.poll(0) if len(pfds) == 1: revents = pfds[0][1] if revents & ovs.poller.POLLERR or revents & ovs.poller.POLLHUP: try: # The following should raise an exception. sock.send("\0".encode(), socket.MSG_DONTWAIT) # (Here's where we end up if it didn't.) # XXX rate-limit vlog.err("poll return POLLERR but send succeeded") return errno.EPROTO except socket.error as e: return get_exception_errno(e) else: return 0 else: return errno.EAGAIN
def test_basics(self): s = socket.socket() e = win32event.CreateEvent(None, 1, 0, None) win32file.WSAEventSelect(s, e, 0) assert win32file.WSAEnumNetworkEvents(s) == {} assert win32file.WSAEnumNetworkEvents(s, e) == {} with pytest.raises(TypeError): win32file.WSAEnumNetworkEvents(s, e, 3) with pytest.raises(TypeError): win32file.WSAEnumNetworkEvents(s, "spam") with pytest.raises(TypeError): win32file.WSAEnumNetworkEvents("spam", e) with pytest.raises(TypeError): win32file.WSAEnumNetworkEvents("spam") f = open("NUL") h = win32file._get_osfhandle(f.fileno()) with pytest.raises(win32file.error): win32file.WSAEnumNetworkEvents(h) with pytest.raises(win32file.error): win32file.WSAEnumNetworkEvents(s, h) try: win32file.WSAEnumNetworkEvents(h) except win32file.error as e: assert e.winerror == win32file.WSAENOTSOCK try: win32file.WSAEnumNetworkEvents(s, h) except win32file.error as e: # According to the docs it would seem reasonable that # this would fail with WSAEINVAL, but it doesn't. assert e.winerror == win32file.WSAENOTSOCK
def SvcDoRun(self): """Starts the XML-RPC Service. This method is invoked when the Windows service manager wants to start this service. This method stays running for the duration of the time the service is running. """ servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE, servicemanager.PYS_SERVICE_STARTING, (self._svc_name_, '')) self._StartXMLRPCServer() if self.rpcserver is None: log.LogError('Could not start XML-RPC server') return wait_for_objects = (self.h_wait_stop, self.h_sock_event) servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE, servicemanager.PYS_SERVICE_STARTED, (self._svc_name_, '')) while True: win32file.WSAEventSelect(self.rpcserver, self.h_sock_event, win32file.FD_ACCEPT) rc = win32event.WaitForMultipleObjects(wait_for_objects, 0, win32event.INFINITE) # win32 WSAEventSelect set the socket to non-blocking mode and won't # allow blocking mode until all NetworkEvent flags are cleared (0). win32file.WSAEventSelect(self.rpcserver, self.h_sock_event, 0) if rc == win32event.WAIT_OBJECT_0: break elif rc == win32event.WAIT_OBJECT_0 + 1: self.rpcserver.handle_request() win32file.WSAEventSelect(self.rpcserver, self.h_sock_event, 0) self.rpcserver.server_close() servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE, servicemanager.PYS_SERVICE_STOPPED, (self._svc_name_, ''))
def test_basics(self): s = socket.socket() e = win32event.CreateEvent(None, 1, 0, None) win32file.WSAEventSelect(s, e, 0) self.assertEquals(win32file.WSAEnumNetworkEvents(s), {}) self.assertEquals(win32file.WSAEnumNetworkEvents(s, e), {}) self.assertRaises(TypeError, win32file.WSAEnumNetworkEvents, s, e, 3) self.assertRaises(TypeError, win32file.WSAEnumNetworkEvents, s, "spam") self.assertRaises(TypeError, win32file.WSAEnumNetworkEvents, "spam", e) self.assertRaises(TypeError, win32file.WSAEnumNetworkEvents, "spam") f = open("NUL") h = win32file._get_osfhandle(f.fileno()) self.assertRaises(win32file.error, win32file.WSAEnumNetworkEvents, h) self.assertRaises(win32file.error, win32file.WSAEnumNetworkEvents, s, h) try: win32file.WSAEnumNetworkEvents(h) except win32file.error, e: self.assertEquals(e.winerror, win32file.WSAENOTSOCK)
def run(self): # Initializes the service self.init() # Creates the updater self.updater = updater.Updater() self.running = True # Handling events... while self.running: # Creates an event to handle IO on the socket socket_event = win32event.CreateEvent(None, True, False, None) win32file.WSAEventSelect(self.updater.management_socket, socket_event, win32file.FD_READ | win32file.FD_CLOSE) # Waits for either an event on the socket or a stop request of the service, waits indefinitely logging.info("Waiting for packet...") event_result = win32event.WaitForMultipleObjects( [socket_event, self.stop_event_handle], 0, win32event.INFINITE) if event_result == win32event.WAIT_TIMEOUT: # Timeout occurred, ignoring... pass elif event_result == win32event.WAIT_OBJECT_0 + 0: # socket_event occurred, The socket has some IO that needs to be handled self.updater.receive_message() if self.updater.message: self.updater.handle_message() elif event_result == win32event.WAIT_OBJECT_0 + 1: # stop_event occurred logging.info( "Request to stop service detected. Stopping service...") self.stop() else: # Error occurred logging.critical("WaitForMultipleObjects failed!") self.stop()
def communication_win(self, is_check): import win32event import win32file import win32api import pywintypes import winerror # event for the socket hEvent_sock = win32event.CreateEvent(None, 0, 0, None) win32file.WSAEventSelect(self.comms_socket, hEvent_sock, win32file.FD_READ) # event, overlapped struct for the pipe or tunnel hEvent_pipe = win32event.CreateEvent(None, 0, 0, None) # for reading from the pipe overlapped_pipe = pywintypes.OVERLAPPED() overlapped_pipe.hEvent = hEvent_pipe # buffer for the packets message_readfile = win32file.AllocateReadBuffer(4096) # showing if we already async reading or not not_reading_already = True first_run = True while not self._stop: try: if not self.tunnel_r: # user is not authenticated yet, so there is no pipe # only checking the socket for data rc = win32event.WaitForSingleObject( hEvent_sock, int(self.timeout * 1000)) if rc == winerror.WAIT_TIMEOUT: # timed out, just rerun and wait continue else: # client mode so we have the socket and tunnel as well # or the client authenticated and the pipe was created if first_run or not_reading_already: # no ReadFile was called before or finished, so we # are calling it again hr, _ = win32file.ReadFile(self.tunnel_r, message_readfile, overlapped_pipe) not_reading_already = first_run = False if (hr == winerror.ERROR_IO_PENDING): # well, this was an async read, so we need to wait # until it happens rc = win32event.WaitForMultipleObjects( [hEvent_sock, hEvent_pipe], 0, int(self.timeout * 1000)) if rc == winerror.WAIT_TIMEOUT: # timed out, just rerun and wait continue else: if hr != 0: common.internal_print( "{0} ReadFile failed: {1}".format( self.module_short, hr), -1) raise if rc < 0x80: # STATUS_ABANDONED_WAIT_0 if rc == 0: # socket got signalled not_reading_already = False messages = self.recv() for message in messages: # looping through the messages from socket if len(message) == 0: # this could happen when the socket died or # partial message was read. continue if common.is_control_channel(message[0:1]): # parse control messages if self.controlchannel.handle_control_messages( self, message[len(common.CONTROL_CHANNEL_BYTE ):], None): continue else: self.stop() break if self.authenticated: try: # write packet to the tunnel self.packet_writer( message[len(common.CONTROL_CHANNEL_BYTE ):]) except OSError as e: print(e) # wut? except Exception as e: if e.args[0] == 995: common.internal_print( "Interface disappered, exiting thread: {0}" .format(e), -1) self.stop() continue if rc == 1: # pipe/tunnel got signalled not_reading_already = True if (overlapped_pipe.InternalHigh < 4) or (message_readfile[0:1] != "\x45"): #Only care about IPv4 # too small which should not happen or not IPv4, so we just drop it. continue # reading out the packet from the buffer and discarding the rest readytogo = message_readfile[0:overlapped_pipe. InternalHigh] self.send(common.DATA_CHANNEL_BYTE, readytogo, None) except win32api.error as e: common.internal_print("TCP Exception: {0}".format(e), -1) self.cleanup() return True
def test_functional(self): # This is not really a unit test, but it does exercise the code # quite well and can serve as an example of WSAEventSelect and # WSAEnumNetworkEvents usage. port = socket.socket() port.setblocking(0) port_event = win32event.CreateEvent(None, 0, 0, None) win32file.WSAEventSelect(port, port_event, win32file.FD_ACCEPT | win32file.FD_CLOSE) port.bind(("127.0.0.1", 0)) port.listen(10) client = socket.socket() client.setblocking(0) client_event = win32event.CreateEvent(None, 0, 0, None) win32file.WSAEventSelect( client, client_event, win32file.FD_CONNECT | win32file.FD_READ | win32file.FD_WRITE | win32file.FD_CLOSE) err = client.connect_ex(port.getsockname()) self.assertEquals(err, win32file.WSAEWOULDBLOCK) res = win32event.WaitForSingleObject(port_event, 1000) self.assertEquals(res, win32event.WAIT_OBJECT_0) events = win32file.WSAEnumNetworkEvents(port, port_event) self.assertEquals(events, {win32file.FD_ACCEPT: 0}) server, addr = port.accept() server.setblocking(0) server_event = win32event.CreateEvent(None, 1, 0, None) win32file.WSAEventSelect( server, server_event, win32file.FD_READ | win32file.FD_WRITE | win32file.FD_CLOSE) res = win32event.WaitForSingleObject(server_event, 1000) self.assertEquals(res, win32event.WAIT_OBJECT_0) events = win32file.WSAEnumNetworkEvents(server, server_event) self.assertEquals(events, {win32file.FD_WRITE: 0}) res = win32event.WaitForSingleObject(client_event, 1000) self.assertEquals(res, win32event.WAIT_OBJECT_0) events = win32file.WSAEnumNetworkEvents(client, client_event) self.assertEquals(events, { win32file.FD_CONNECT: 0, win32file.FD_WRITE: 0 }) sent = 0 data = str2bytes("x") * 16 * 1024 while sent < 16 * 1024 * 1024: try: sent += client.send(data) except socket.error as e: if e.args[0] == win32file.WSAEINTR: continue elif e.args[0] in (win32file.WSAEWOULDBLOCK, win32file.WSAENOBUFS): break else: raise else: self.fail("could not find socket buffer limit") events = win32file.WSAEnumNetworkEvents(client) self.assertEquals(events, {}) res = win32event.WaitForSingleObject(server_event, 1000) self.assertEquals(res, win32event.WAIT_OBJECT_0) events = win32file.WSAEnumNetworkEvents(server, server_event) self.assertEquals(events, {win32file.FD_READ: 0}) received = 0 while received < sent: try: received += len(server.recv(16 * 1024)) except socket.error as e: if e.args[0] in [win32file.WSAEINTR, win32file.WSAEWOULDBLOCK]: continue else: raise self.assertEquals(received, sent) events = win32file.WSAEnumNetworkEvents(server) self.assertEquals(events, {}) res = win32event.WaitForSingleObject(client_event, 1000) self.assertEquals(res, win32event.WAIT_OBJECT_0) events = win32file.WSAEnumNetworkEvents(client, client_event) self.assertEquals(events, {win32file.FD_WRITE: 0}) client.shutdown(socket.SHUT_WR) res = win32event.WaitForSingleObject(server_event, 1000) self.assertEquals(res, win32event.WAIT_OBJECT_0) # strange timing issues... for i in range(5): events = win32file.WSAEnumNetworkEvents(server, server_event) if events: break win32api.Sleep(100) else: raise AssertionError("failed to get events") self.assertEquals(events, {win32file.FD_CLOSE: 0}) events = win32file.WSAEnumNetworkEvents(client) self.assertEquals(events, {}) server.close() res = win32event.WaitForSingleObject(client_event, 1000) self.assertEquals(res, win32event.WAIT_OBJECT_0) events = win32file.WSAEnumNetworkEvents(client, client_event) self.assertEquals(events, {win32file.FD_CLOSE: 0}) client.close() events = win32file.WSAEnumNetworkEvents(port) self.assertEquals(events, {})
def communication_win(self, is_check): import win32event import win32file import win32api import pywintypes import winerror # event for the socket hEvent_sock = win32event.CreateEvent(None, 0, 0, None) win32file.WSAEventSelect(self.comms_socket, hEvent_sock, win32file.FD_READ) # descriptor list self.rlist = [self.comms_socket] # overlapped list self.olist = [0] # event list self.elist = [hEvent_sock] # message buffer list self.mlist = [0] # id of the read object - put in this if it was read self.ulist = [] if not self.serverorclient and self.tunnel: # client mode # objects created for the tunnel and put in the corresponding # lists hEvent_pipe = win32event.CreateEvent( None, 0, 0, None) # for reading from the pipe overlapped_pipe = pywintypes.OVERLAPPED() overlapped_pipe.hEvent = hEvent_pipe message_buffer = win32file.AllocateReadBuffer(4096) self.rlist.append(self.tunnel) self.olist.append(overlapped_pipe) self.elist.append(hEvent_pipe) self.mlist.append(message_buffer) self.ulist.append(1) while not self._stop: try: if not self.tunnel: # check or server mode without client only with socket #message, addr = self.comms_socket.recvfrom(1508) rc = win32event.WaitForSingleObject( hEvent_sock, int(self.timeout * 1000)) if rc == winerror.WAIT_TIMEOUT: # timed out, just rerun and wait continue else: if self.ulist: # there is somebody waiting to be read for idx in self.ulist: # issueing ReadFile on all not yet read mailslots/tunnel hr, _ = win32file.ReadFile(self.rlist[idx], self.mlist[idx], self.olist[idx]) if (hr != 0) and (hr != winerror.ERROR_IO_PENDING): common.internal_print( "UDP ReadFile failed: {0}".format(hr), -1) raise self.ulist = [] # waiting to get some data somewhere rc = win32event.WaitForMultipleObjects( self.elist, 0, int(self.timeout * 1000)) if rc == winerror.WAIT_TIMEOUT: # timed out, just rerun and wait continue if rc < 0x80: # STATUS_ABANDONED_WAIT_0 if rc > 0: # the tunnel or one of the mailslots got signalled self.ulist.append(rc) if (self.olist[rc].InternalHigh < 4) or (self.mlist[rc][0:1] != "\x45"): #Only care about IPv4 continue readytogo = self.mlist[rc][0:self.olist[rc]. InternalHigh] if self.serverorclient: c = self.lookup_client_priv(readytogo) if c: # if the differece between the received and set sequences too big # some routers/firewalls just drop older sequences. If it gets # too big, we just drop the older ones and use the latest X packet # this helps on stabality. if (c.get_ICMP_received_sequence() - c.get_ICMP_sent_sequence() ) >= self.TRACKING_THRESHOLD: c.set_ICMP_sent_sequence( c.get_ICMP_received_sequence() - self.TRACKING_ADJUST) # get client related values: identifier and sequence number identifier = c.get_ICMP_sent_identifier() sequence = c.get_ICMP_sent_sequence() # queueing every packet first c.queue_put(readytogo) # are there any packets to answer? if (c.get_ICMP_received_sequence() - sequence) == 0: continue else: request_num = 0 # if there is less packet than that we have in the queue # then we cap the outgoing packet number if (c.get_ICMP_received_sequence() - sequence) < (c.queue_length()): number_to_get = ( c.get_ICMP_received_sequence() - sequence) else: # send all packets from the queue number_to_get = c.queue_length() for i in range(0, number_to_get): # get first packet readytogo = c.queue_get() # is it he last one we are sending now? if i == (number_to_get - 1): # if the last one and there is more in the queue # then we ask for dummy packets request_num = c.queue_length() # go packets go! self.send(common.DATA_CHANNEL_BYTE, readytogo, ((socket.inet_ntoa( c.get_public_ip_addr()), c.get_public_src_port()), identifier, sequence + i + 1, request_num)) sequence = (sequence + i + 1) % 65536 c.set_ICMP_sent_sequence(sequence) else: # there is no client with that IP common.internal_print( "Client not found, strange?!", 0, self.verbosity, common.DEBUG) continue else: if self.authenticated: # whatever we have from the tunnel, just encapsulate it # and send it out self.ICMP_sequence = (self.ICMP_sequence + 1) % 65536 self.send( common.DATA_CHANNEL_BYTE, readytogo, (self.server_tuple, self.ICMP_identifier, self.ICMP_sequence, 0)) #?? else: common.internal_print( "Spoofed packets, strange?!", 0, self.verbosity, common.DEBUG) continue if rc == 0: # socket got signalled message, addr, identifier, sequence, queue_length = self.recv( ) if len(message) == 0: continue c = None if self.serverorclient: self.authenticated = False c = self.lookup_client_pub((addr, 0)) if c: c.set_ICMP_received_identifier(identifier) # packets does not arrive in order sometime # if higher sequence arrived already, then we # do not modify # 16bit integer MAX could be a bit tricky, a # threshold had to be introduced to make it # fail safe. Hacky but should work. ICMP_THRESHOLD = 100 if (sequence > c.get_ICMP_received_sequence() ) or ((sequence < ICMP_THRESHOLD) and ((sequence + 65536) > c.get_ICMP_received_sequence()) and (c.get_ICMP_received_sequence() > ICMP_THRESHOLD)): c.set_ICMP_received_sequence(sequence) else: if queue_length: common.internal_print( "sending {0} dummy packets".format( queue_length), 0, self.verbosity, common.DEBUG) for i in range(queue_length + 10): self.ICMP_sequence = (self.ICMP_sequence + 1) % 65536 self.do_dummy_packet( self.ICMP_identifier, self.ICMP_sequence) if common.is_control_channel(message[0:1]): if self.controlchannel.handle_control_messages( self, message[len(common.CONTROL_CHANNEL_BYTE):], (addr, identifier, sequence, 0)): continue else: self.stop() break if c: self.authenticated = c.get_authenticated() if self.authenticated: try: self.packet_writer( message[len(common.CONTROL_CHANNEL_BYTE):]) except OSError as e: print(e) except win32api.error as e: common.internal_print("UDP Exception: {0}".format(e), -1) except socket.error as se: if se.args[0] == 10054: # port is unreachable common.internal_print( "Server's port is unreachable: {0}".format(se), -1) self._stop = True return True
def communication_win(self, is_check): import win32event import win32file import win32api import pywintypes import winerror # event for the socket hEvent_sock = win32event.CreateEvent(None, 0, 0, None) win32file.WSAEventSelect(self.comms_socket, hEvent_sock, win32file.FD_READ) # descriptor list self.rlist = [self.comms_socket] # overlapped list self.olist = [0] # event list self.elist = [hEvent_sock] # message buffer list self.mlist = [0] # id of the read object - put in this if it was read self.ulist = [] if not self.serverorclient and self.tunnel: # client mode # objects created for the tunnel and put in the corresponding # lists hEvent_pipe = win32event.CreateEvent( None, 0, 0, None) # for reading from the pipe overlapped_pipe = pywintypes.OVERLAPPED() overlapped_pipe.hEvent = hEvent_pipe message_buffer = win32file.AllocateReadBuffer(4096) self.rlist.append(self.tunnel) self.olist.append(overlapped_pipe) self.elist.append(hEvent_pipe) self.mlist.append(message_buffer) self.ulist.append(1) while not self._stop: try: if not self.tunnel: # check or server mode without client only with socket rc = win32event.WaitForSingleObject( hEvent_sock, int(self.timeout * 1000)) if rc == winerror.WAIT_TIMEOUT: # timed out, just rerun and wait continue else: if self.ulist: # there is somebody waiting to be read for idx in self.ulist: # issueing ReadFile on all not yet read mailslots/tunnel hr, _ = win32file.ReadFile(self.rlist[idx], self.mlist[idx], self.olist[idx]) if (hr != 0) and (hr != winerror.ERROR_IO_PENDING): common.internal_print( "UDP ReadFile failed: {0}".format(hr), -1) raise self.ulist = [] # waiting to get some data somewhere rc = win32event.WaitForMultipleObjects( self.elist, 0, int(self.timeout * 1000)) if rc == winerror.WAIT_TIMEOUT: # timed out, just rerun and wait continue if rc < 0x80: # STATUS_ABANDONED_WAIT_0 if rc > 0: # the tunnel or one of the mailslots got signalled self.ulist.append(rc) if (self.olist[rc].InternalHigh < 4) or (self.mlist[rc][0:1] != "\x45"): #Only care about IPv4 continue readytogo = self.mlist[rc][0:self.olist[rc]. InternalHigh] if self.serverorclient: c = self.lookup_client_priv(readytogo) if c: self.send( common.DATA_CHANNEL_BYTE, readytogo, ((socket.inet_ntoa(c.get_public_ip_addr()), c.get_public_src_port()), None)) else: common.internal_print( "Client not found, strange?!", 0, self.verbosity, common.DEBUG) continue else: if self.authenticated: self.send(common.DATA_CHANNEL_BYTE, readytogo, (self.server_tuple, None)) if rc == 0: # socket got signalled messages = self.recv() if len(messages) == 0: continue for addr in messages: for message in messages[addr]: c = None if self.serverorclient: self.authenticated = False c = self.lookup_client_pub((addr, 0)) if common.is_control_channel(message[0:1]): if self.controlchannel.handle_control_messages( self, message[len( common.CONTROL_CHANNEL_BYTE):], (addr, None)): continue else: self.stop() break if c: self.authenticated = c.get_authenticated() if self.authenticated: try: self.packet_writer(message[ len(common.CONTROL_CHANNEL_BYTE):]) except OSError as e: print(e) except win32api.error as e: common.internal_print("UDP Exception: {0}".format(e), -1) except socket.error as se: if se.args[0] == 10054: # port is unreachable common.internal_print( "Server's port is unreachable: {0}".format(se), -1) self._stop = True return True