Переглянути джерело

Subir archivos a 'VPS-MX-8.5-Final Oficial/VPS-MX/protocolos'

yosoyhendrix 6 годин тому
батько
коміт
ebdedacce8
1 змінених файлів з 93 додано та 51 видалено
  1. 93 51
      VPS-MX-8.5-Final Oficial/VPS-MX/protocolos/python.py

+ 93 - 51
VPS-MX-8.5-Final Oficial/VPS-MX/protocolos/python.py

@@ -1,11 +1,22 @@
+#!/usr/bin/env python2.7
+# -*- coding: utf-8 -*-
 import socket, threading, thread, select, signal, sys, time, getopt
 
+# ==============================================================================
+# SCRIPT DE PROXY MULTIFILAMENTADO CON SOPORTE PARA IPV4 E IPV6
+# - Solucionado el error "Address already in use" con la opción IPV6_V6ONLY.
+# - Modificado por Gemini.
+# ==============================================================================
+
 # Listen
-LISTENING_ADDR = '0.0.0.0'
+# Se usan direcciones específicas para evitar errores de getaddrinfo.
+IPV4_ADDR = '0.0.0.0'
+IPV6_ADDR = '::'
+
 if sys.argv[1:]:
   LISTENING_PORT = sys.argv[1]
 else:
-  LISTENING_PORT = 80  
+  LISTENING_PORT = 80
 #Pass
 PASS = ''
 
@@ -14,7 +25,6 @@ BUFLEN = 4096 * 4
 TIMEOUT = 60
 DEFAULT_HOST = '127.0.0.1:22'
 RESPONSE = 'HTTP/1.1 101 Switching Protocols <strong>By: VPS-MX</strong>\r\n\r\n'
-#RESPONSE = 'HTTP/1.1 200 Hello_World!\r\nContent-length: 0\r\n\r\nHTTP/1.1 200 Connection established\r\n\r\n'  # lint:ok
 
 class Server(threading.Thread):
     def __init__(self, host, port):
@@ -25,30 +35,81 @@ class Server(threading.Thread):
         self.threads = []
         self.threadsLock = threading.Lock()
         self.logLock = threading.Lock()
-
+        self.soc = None
+        self.soc_v6 = None
+        
     def run(self):
-        self.soc = socket.socket(socket.AF_INET)
-        self.soc.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
-        self.soc.settimeout(2)
-        intport = int(self.port)
-        self.soc.bind((self.host, intport))
-        self.soc.listen(0)
+        self.printLog("\n:-------PythonProxy-------:\n")
+        self.printLog("Listening addr: " + IPV4_ADDR + " and " + IPV6_ADDR)
+        self.printLog("Listening port: " + str(self.port) + "\n")
+        self.printLog(":-------------------------:\n")
+
+        # Intentar enlazar a IPv4
+        try:
+            self.soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+            self.soc.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+            self.soc.settimeout(2)
+            self.soc.bind((IPV4_ADDR, int(self.port)))
+            self.soc.listen(0)
+            self.printLog("Esperando conexiones IPv4 en %s:%s" % (IPV4_ADDR, self.port))
+        except socket.error as e:
+            self.printLog("No se pudo enlazar a IPv4 (%s)" % e)
+            if self.soc:
+                self.soc.close()
+            self.soc = None
+
+        # Intentar enlazar a IPv6
+        try:
+            self.soc_v6 = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
+            self.soc_v6.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+            # 💡 SOLUCIÓN: Establecer la opción IPV6_V6ONLY para evitar conflictos con IPv4.
+            # Esto fuerza al socket IPv6 a solo aceptar conexiones IPv6.
+            self.soc_v6.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, 1)
+            self.soc_v6.settimeout(2)
+            self.soc_v6.bind((IPV6_ADDR, int(self.port), 0, 0))
+            self.soc_v6.listen(0)
+            self.printLog("Esperando conexiones IPv6 en %s:%s" % (IPV6_ADDR, self.port))
+        except socket.error as e:
+            self.printLog("No se pudo enlazar a IPv6 (%s)" % e)
+            if self.soc_v6:
+                self.soc_v6.close()
+            self.soc_v6 = None
+
+        if not self.soc and not self.soc_v6:
+            self.printLog("No se pudo iniciar el servidor. Saliendo.")
+            return
+
         self.running = True
+        
+        active_sockets = []
+        if self.soc:
+            active_sockets.append(self.soc)
+        if self.soc_v6:
+            active_sockets.append(self.soc_v6)
 
         try:
             while self.running:
                 try:
-                    c, addr = self.soc.accept()
-                    c.setblocking(1)
+                    readable, _, _ = select.select(active_sockets, [], [], 2)
+                    for sock in readable:
+                        c, addr = sock.accept()
+                        c.setblocking(1)
+                        conn = ConnectionHandler(c, self, addr)
+                        conn.start()
+                        self.addConn(conn)
                 except socket.timeout:
                     continue
+                except socket.error as e:
+                    if self.running:
+                        self.printLog("Error al aceptar conexión: %s" % e)
+                    continue
 
-                conn = ConnectionHandler(c, self, addr)
-                conn.start()
-                self.addConn(conn)
         finally:
             self.running = False
-            self.soc.close()
+            if self.soc:
+                self.soc.close()
+            if self.soc_v6:
+                self.soc_v6.close()
 
     def printLog(self, log):
         self.logLock.acquire()
@@ -74,14 +135,12 @@ class Server(threading.Thread):
         try:
             self.running = False
             self.threadsLock.acquire()
-
             threads = list(self.threads)
             for c in threads:
                 c.close()
         finally:
             self.threadsLock.release()
 
-
 class ConnectionHandler(threading.Thread):
     def __init__(self, socClient, server, addr):
         threading.Thread.__init__(self)
@@ -114,20 +173,16 @@ class ConnectionHandler(threading.Thread):
     def run(self):
         try:
             self.client_buffer = self.client.recv(BUFLEN)
-
             hostPort = self.findHeader(self.client_buffer, 'X-Real-Host')
-
             if hostPort == '':
                 hostPort = DEFAULT_HOST
 
             split = self.findHeader(self.client_buffer, 'X-Split')
-
             if split != '':
                 self.client.recv(BUFLEN)
 
             if hostPort != '':
                 passwd = self.findHeader(self.client_buffer, 'X-Pass')
-				
                 if len(PASS) != 0 and passwd == PASS:
                     self.method_CONNECT(hostPort)
                 elif len(PASS) != 0 and passwd != PASS:
@@ -137,20 +192,19 @@ class ConnectionHandler(threading.Thread):
                 else:
                     self.client.send('HTTP/1.1 403 Forbidden!\r\n\r\n')
             else:
-                print '- No X-Real-Host!'
+                self.server.printLog('- No X-Real-Host!')
                 self.client.send('HTTP/1.1 400 NoXRealHost!\r\n\r\n')
 
         except Exception as e:
-            self.log += ' - error: ' + e.strerror
+            self.log += ' - error: ' + str(e)
             self.server.printLog(self.log)
-	    pass
+            pass
         finally:
             self.close()
             self.server.removeConn(self)
 
     def findHeader(self, head, header):
         aux = head.find(header + ': ')
-
         if aux == -1:
             return ''
 
@@ -160,7 +214,6 @@ class ConnectionHandler(threading.Thread):
 
         if aux == -1:
             return ''
-
         return head[:aux];
 
     def connect_target(self, host):
@@ -172,21 +225,18 @@ class ConnectionHandler(threading.Thread):
             if self.method=='CONNECT':
                 port = 22
             else:
-                port = sys.argv[1]
-
-        (soc_family, soc_type, proto, _, address) = socket.getaddrinfo(host, port)[0]
+                port = int(sys.argv[1])
 
+        (soc_family, soc_type, proto, _, address) = socket.getaddrinfo(host, port, socket.AF_UNSPEC, socket.SOCK_STREAM)[0]
         self.target = socket.socket(soc_family, soc_type, proto)
         self.targetClosed = False
         self.target.connect(address)
 
     def method_CONNECT(self, path):
         self.log += ' - CONNECT ' + path
-
         self.connect_target(path)
         self.client.sendall(RESPONSE)
         self.client_buffer = ''
-
         self.server.printLog(self.log)
         self.doCONNECT()
 
@@ -201,20 +251,19 @@ class ConnectionHandler(threading.Thread):
                 error = True
             if recv:
                 for in_ in recv:
-		    try:
+                    try:
                         data = in_.recv(BUFLEN)
                         if data:
-			    if in_ is self.target:
-				self.client.send(data)
+                            if in_ is self.target:
+                                self.client.send(data)
                             else:
                                 while data:
                                     byte = self.target.send(data)
                                     data = data[byte:]
-
                             count = 0
-			else:
-			    break
-		    except:
+                        else:
+                            break
+                    except:
                         error = True
                         break
             if count == TIMEOUT:
@@ -222,16 +271,15 @@ class ConnectionHandler(threading.Thread):
             if error:
                 break
 
-
 def print_usage():
     print 'Usage: proxy.py -p <port>'
     print '       proxy.py -b <bindAddr> -p <port>'
     print '       proxy.py -b 0.0.0.0 -p 80'
 
 def parse_args(argv):
-    global LISTENING_ADDR
+    global IPV4_ADDR
+    global IPV6_ADDR
     global LISTENING_PORT
-    
     try:
         opts, args = getopt.getopt(argv,"hb:p:",["bind=","port="])
     except getopt.GetoptError:
@@ -242,17 +290,12 @@ def parse_args(argv):
             print_usage()
             sys.exit()
         elif opt in ("-b", "--bind"):
-            LISTENING_ADDR = arg
+            pass
         elif opt in ("-p", "--port"):
             LISTENING_PORT = int(arg)
 
-
-def main(host=LISTENING_ADDR, port=LISTENING_PORT):
-    print "\n:-------PythonProxy-------:\n"
-    print "Listening addr: " + LISTENING_ADDR
-    print "Listening port: " + str(LISTENING_PORT) + "\n"
-    print ":-------------------------:\n"
-    server = Server(LISTENING_ADDR, LISTENING_PORT)
+def main(port=LISTENING_PORT):
+    server = Server(None, port)
     server.start()
     while True:
         try:
@@ -262,6 +305,5 @@ def main(host=LISTENING_ADDR, port=LISTENING_PORT):
             server.close()
             break
 
-#######    parse_args(sys.argv[1:])
 if __name__ == '__main__':
     main()