Frage

Ich bin in dem Prozess einen Service der Umsetzung - mit dem Twisted-Framework in Python geschrieben, auf Debian GNU / Linux -, die die Verfügbarkeit von SIP-Servern überprüft. Dazu verwende ich die OPTIONS-Methode (eine SIP-Protokoll-Funktion), da dies eine Binse Praxis zu sein scheint. Um eine korrekte und RFC-konformen Header zu konstruieren, muss ich die Quell-IP-Adresse und den Quell-Port für die Verbindung wissen, die hergestellt werden soll. [Wie] kann dies mit Verdrehte getan werden?

Das ist, was ich versucht: Ich subclassed protocol.DatagramProtocol und innerhalb startProtocol(self) ich benutzte self.transport.getHost().host und self.transport.getHost().port. Letzteres ist in der Tat der Port, der verwendet werden wird, während nur die erstere ergibt 0.0.0.0.

Ich denke, dass Verdreht an dieser Stelle nicht [noch?] Wissen, welche Schnittstelle und als solche welche Quell-IP-Adresse verwendet. Bietet Verdreht eine Einrichtung, die mir dabei helfen könnte, oder muss ich mit dem Betriebssystem (Routing) in einer anderen Art und Weise verbinden müssen? Oder habe ich nur self.transport.getHost().host nicht ordnungsgemäß verwenden?

War es hilfreich?

Lösung

Aus Gründen der Vollständigkeit, antworte ich meine eigene Frage:

Stellen Sie sicher, () auf dem Transport verwenden verbinden, bevor Sie die Host-Quell-IP-Adresse zu ermitteln. Der folgende Auszug zeigt den relevanten Teil einer Protokollimplementierung:

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

Andere Tipps

Wenn Sie mit UDP dann der Endpunkt durch entweder bestimmt wird:

  1. bind() auf dem Socket und explizit eine Adresse geben
  2. Senden eines Pakets

Wenn Sie ein paar weitere Details möchten, überprüfen Sie diese Antwort .

Das Problem ist, dass ich mit verdrehtem nicht so vertraut bin. Von dem, was ich durch eine schnelle Durchsicht der Quelle kann sagen, es sieht aus wie Sie einen Reaktor wie t.i.d.SelectReactor statt. Dies ist, was t.n.d.DNSDatagramProtocol tut unter die Haube .

Wenn Sie twisted aus dem Bild nehmen, dann der folgenden Code-Schnipsel zeigt, was los ist:

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

Holen Sie sich das Host-Name ist ein wenig komplizierter, wenn Sie mehrere Netzwerk-Schnittstellen oder IPv4 und IPv6 unterstützen müssen. Wenn Sie die verwendete Schnittstelle konfigurierbar machen können, ist es dann als erstes Mitglied des Tupels übergeben, um socket.bind() und Sie werden eingestellt.

Jetzt ist der harte Teil tut dies innerhalb der Grenzen der Abstraktionen, die bieten verdreht. Leider kann ich nicht viel da helfen. Ich würde empfehlen, für Beispiele suchen, wie Sie Zugriff auf den zugrunde liegenden Sockel zu bekommen oder einen Weg finden, die Socket-Informationen in den Rahmen zu übergeben.

Viel Glück.

Haben Sie sehen, ob das was Sie tun wollen, ist mit dem SIP-Implementierung, die Teil von Verdreht ist?

In jedem Fall, wie Sie die Quelladresse und den Port für UDP in Twisted-Set ist ganz ähnlich, wie man sie ohne Verdrehte gesetzt. In Verdreht, bindet reactor.listenUDP(port, protocol, interface) einen UDP-Socket an einen bestimmten Port und Schnittstelle und verarbeitet die empfangenen Datagramme zu Ihrem Protokoll. Im Innern des Protokolls sendet self.transport.write(msg, addr) ein Datagramm mit der Adresse addr, die das Protokoll als Quelladresse gebunden ist.

Lesen Sie Ihre Frage noch einmal, ich glaube, das einzige Teil, das Sie interface zu reactor.listenUDP(...) fehlten vorging.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top