Question

Je suis en train de mettre en œuvre un service - écrit en Python avec le framework Twisted, fonctionnant sous Debian GNU / Linux - qui vérifie la disponibilité des serveurs SIP. Pour cela, j'utilise la méthode OPTIONS (une fonctionnalité du protocole SIP), car cela semble être une pratique courante. Afin de construire des en-têtes corrects et conformes aux RFC, j'ai besoin de connaître l'adresse IP source et le port source de la connexion à établir. [Comment] est-ce possible avec Twisted?

C'est ce que j'ai essayé: Je sous-classe protocol.DatagramProtocol et au sein de < code> startProtocol (self) J'ai utilisé self.transport.getHost (). host et self.transport.getHost (). port . Ce dernier est en effet le port qui sera utilisé, alors que le premier ne donne que 0.0.0.0.

Je suppose qu’à ce stade, Twisted ne [sait pas encore] quelle interface et, en tant que telle, quelle adresse IP source sera utilisée. Est-ce que Twisted fournit une installation qui pourrait m'aider avec ceci ou dois-je avoir une interface avec l'OS (routage) d'une manière différente? Ou ai-je simplement utilisé self.transport.getHost (). Host de manière incorrecte?

Était-ce utile?

La solution

Par souci d'exhaustivité, je réponds à ma propre question:

Assurez-vous d’utiliser connect () sur le transport avant de tenter de déterminer l’adresse IP source de l’hôte. L'extrait suivant montre la partie pertinente d'une implémentation de protocole:

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

Autres conseils

Si vous utilisez UDP, le point de terminaison est déterminé par:

  1. appeler bind () sur le socket et lui donner explicitement une adresse
  2. envoi d'un paquet

Si vous souhaitez quelques informations supplémentaires, consultez cette réponse . .

Le problème est que je ne connais pas très bien les tordus. D'après ce que je peux dire en parcourant rapidement le code source, il semble que vous souhaitiez utiliser un réacteur tel que tidSelectReactor à la place. C’est ce que tndDNSDatagramProtocol fait sous le capot .

Si vous supprimez twisted de la photo, l'extrait suivant indique ce qui se passe:

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

Obtenir le nom d’hôte est un peu plus compliqué si vous devez prendre en charge plusieurs interfaces réseau ou IPv4 et IPv6. Si vous pouvez rendre l'interface utilisée configurable, transmettez-la en tant que premier membre du tuple à socket.bind () et vous êtes défini.

Maintenant, la partie la plus difficile consiste à le faire dans les limites des abstractions fournies. Malheureusement, je ne peux pas aider beaucoup là-bas. Je recommanderais de rechercher des exemples sur la manière d’obtenir un accès au socket sous-jacent ou de trouver un moyen de transmettre les informations du socket au cadre.

Bonne chance.

Avez-vous vu si cela était possible avec l'implémentation SIP intégrée à Twisted?

Dans tous les cas, la manière dont vous définissez l’adresse source et le port pour UDP dans Twisted est assez similaire à celle que vous définissez sans Twisted. Dans Twisted, réacteur.listenUDP (port, protocole, interface) lie un socket UDP à un port et à une interface spécifiques et traite les datagrammes reçus avec votre protocole. Dans le protocole, self.transport.write (msg, addr) envoie un datagramme à addr en utilisant l'adresse à laquelle le protocole est lié en tant qu'adresse source.

En relisant votre question, je pense que la seule chose qui vous manquait était de passer de interface à réacteur.listenUDP (...) .

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top