Pregunta

Estoy en el proceso de implementar un servicio, escrito en Python con el marco Twisted, que se ejecuta en Debian GNU / Linux, que verifica la disponibilidad de los servidores SIP. Para esto utilizo el método OPTIONS (una función de protocolo SIP), ya que esto parece ser una práctica común. Para construir encabezados correctos y compatibles con RFC, necesito saber la dirección IP de origen y el puerto de origen para la conexión que se establecerá. [¿Cómo] se puede hacer esto con Twisted?

Esto es lo que probé: Subclasifiqué protocol.DatagramProtocol y dentro de < code> startProtocol (self) Utilicé self.transport.getHost (). host y self.transport.getHost (). port . Este último es el puerto que se utilizará, mientras que el primero solo produce 0.0.0.0.

Supongo que en este punto Twisted no sabe [todavía?] qué interfaz y, como tal, qué dirección IP de origen se utilizará. ¿Twisted proporciona una instalación que podría ayudarme con esto o necesito interactuar con el sistema operativo (enrutamiento) de una manera diferente? ¿O acabo de usar self.transport.getHost (). Host incorrectamente?

¿Fue útil?

Solución

En aras de la exhaustividad, respondo mi propia pregunta:

Asegúrese de usar connect () en el transporte antes de intentar determinar la dirección IP de origen del host. El siguiente extracto muestra la parte relevante de la implementación de un protocolo:

class FooBarProtocol(protocol.DatagramProtocol):
    def startProtocol(self):
        self.transport.getHost().host   # => 0.0.0.0
        self.transport.connect(self.dstHost, self.dstPort)
        self.transport.getHost().host   # => 192.168.1.102

Otros consejos

Si está utilizando UDP, el punto final está determinado por:

  1. llamando a bind () en el zócalo y dándole explícitamente una dirección
  2. enviando un paquete

Si desea algunos detalles más, verifique esta respuesta .

El problema es que no estoy tan familiarizado con retorcido. Por lo que puedo decir por una lectura rápida de la fuente, parece que es posible que desee utilizar un reactor como tidSelectReactor en su lugar. Esto es lo que tndDNSDatagramProtocol lo hace bajo el capó .

Si retira twisted de la imagen, el siguiente fragmento muestra lo que está sucediendo:

>>> import socket
>>> s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, 0)
<socket._socketobject object at 0x10025d670>
>>> s.getsockname()           # this is an unbound or unnamed socket
('0.0.0.0', 0)
>>> s.bind( ('0.0.0.0', 0) )  # 0.0.0.0 is INADDR_ANY, 0 means pick a port
>>> s.getsockname()           # IP is still zero, but it has picked a port
('0.0.0.0', 56814)

Obtener el nombre de host es un poco más complicado si necesita admitir múltiples interfaces de red o IPv4 e IPv6. Si puede hacer que la interfaz utilizada sea configurable, páselo como el primer miembro de la tupla a socket.bind () y estará listo.

Ahora la parte difícil es hacer esto dentro de los límites de las abstracciones que proporciona retorcido. Desafortunadamente, no puedo ayudar mucho allí. Recomendaría buscar ejemplos sobre cómo puede obtener acceso al socket subyacente o encontrar una manera de pasar la información del socket al marco.

Buena suerte.

¿Viste si eso es posible con la implementación SIP que forma parte de Twisted?

En cualquier caso, la forma en que configura la dirección de origen y el puerto para UDP en Twisted es bastante similar a cómo los configura sin Twisted. En Twisted, reactor.listenUDP (puerto, protocolo, interfaz) une un socket UDP a un puerto e interfaz específicos y maneja los datagramas recibidos a su protocolo. Dentro del protocolo, self.transport.write (msg, addr) envía un datagrama a addr utilizando la dirección a la que está vinculado el protocolo como dirección de origen.

Leyendo su pregunta nuevamente, creo que la única parte que le faltaba era pasar la interfaz a reactor.listenUDP (...) .

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top