Domanda

Sto implementando un servizio - scritto in Python con il framework Twisted, in esecuzione su Debian GNU / Linux - che controlla la disponibilità dei server SIP. Per questo utilizzo il metodo OPTIONS (una funzione del protocollo SIP), poiché questa sembra essere una pratica comune. Per costruire intestazioni corrette e conformi a RFC, devo conoscere l'indirizzo IP di origine e la porta di origine per la connessione che verrà stabilita. [Come] può essere fatto con Twisted?

Questo è quello che ho provato: Ho eseguito la sottoclasse del protocol.DatagramProtocol ed entro < code> startProtocol (self) Ho usato self.transport.getHost (). host e self.transport.getHost (). port . Quest'ultimo è in effetti la porta che verrà utilizzata, mentre il primo produce solo 0.0.0.0.

Immagino che a questo punto Twisted non [ancora?] sappia quale interfaccia e come tale quale indirizzo IP sorgente verrà usato. Twisted offre una funzione che potrebbe aiutarmi in questo caso o devo interfacciarmi con il sistema operativo (routing) in modo diverso? Oppure ho usato self.transport.getHost (). Host in modo errato?

È stato utile?

Soluzione

Per completezza, rispondo alla mia domanda:

Assicurarsi di utilizzare connect () sul trasporto prima di provare a determinare l'indirizzo IP di origine dell'host. Il seguente estratto mostra la parte rilevante di un'implementazione del protocollo:

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

Altri suggerimenti

Se si utilizza UDP, l'endpoint è determinato da:

  1. chiamando bind () sul socket e assegnandogli esplicitamente un indirizzo
  2. invio di un pacchetto

Se desideri qualche altro dettaglio, controlla questa risposta .

Il problema è che non ho molta familiarità con il twisted. Da quello che posso dire da una rapida lettura della fonte, sembra che potresti voler usare un reattore come tidSelectReactor . Questo è ciò che tndDNSDatagramProtocol fa sotto il cofano .

Se estrai contorto dall'immagine, il frammento seguente mostra cosa sta succedendo:

>>> 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)

Ottenere il nome host è un po 'più complicato se è necessario supportare più interfacce di rete o IPv4 e IPv6. Se puoi rendere configurabile l'interfaccia utilizzata, passala come primo membro della tupla a socket.bind () e sei pronto.

Ora la parte difficile sta facendo questo entro i confini delle astrazioni fornite da twisted. Sfortunatamente, non posso aiutare molto lì. Consiglierei di cercare esempi su come ottenere l'accesso al socket sottostante o trovare un modo per passare le informazioni sul socket nel framework.

Buona fortuna.

Hai visto se ciò che vuoi fare è possibile con l'implementazione SIP che fa parte di Twisted?

In ogni caso, come impostare l'indirizzo e la porta di origine per UDP in Twisted è abbastanza simile a come li si imposta senza Twisted. In Twisted, reattor.listenUDP (porta, protocollo, interfaccia) collega un socket UDP a una porta e un'interfaccia specifiche e gestisce i datagrammi ricevuti con il protocollo. All'interno del protocollo, self.transport.write (msg, addr) invia un datagramma a addr utilizzando l'indirizzo a cui il protocollo è associato come indirizzo di origine.

Rileggendo la tua domanda, penso che l'unica parte che ti mancava fosse passare interfaccia a reattor.listenUDP (...) .

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top