Twisted:出站连接的源 IP 地址
我正在实现一项服务——使用 Twisted 框架用 Python 编写,在 Debian GNU/Linux 上运行——检查 SIP 服务器的可用性。为此,我使用 OPTIONS 方法(SIP 协议功能),因为这似乎是一种常见的做法。为了构造正确且符合 RFC 的标头,我需要知道要建立的连接的源 IP 地址和源端口。 [如何]使用 Twisted 来完成此操作?
这是我尝试过的: 我对 protocol.DatagramProtocol 进行了子类化并在 < code>startProtocol(self) 我使用了 self.transport.getHost().host
和 self.transport.getHost().port
。后者确实是要使用的端口,而前者仅产生 0.0.0.0。
我猜此时 Twisted 还不知道将使用哪个接口以及哪个源 IP 地址。 Twisted 是否提供了可以帮助我解决此问题的工具,或者我是否需要以不同的方式与操作系统(路由)进行交互?或者我只是错误地使用了 self.transport.getHost().host ?
I'm in the process of implementing a service -- written in Python with the Twisted framework, running on Debian GNU/Linux -- that checks the availability of SIP servers. For this I use the OPTIONS method (a SIP protocol feature), as this seems to be a commonplace practice. In order to construct correct and RFC compliant headers, I need to know the source IP address and the source port for the connection that is going to be established. [How] can this be done with Twisted?
This is what I tried:
I subclassed protocol.DatagramProtocol and within startProtocol(self)
I used self.transport.getHost().host
and self.transport.getHost().port
. The latter is indeed the port that's going to be used, whereas the former only yields 0.0.0.0.
I guess that at this point Twisted doesn't [yet?] know which interface and as such which source IP address will be used. Does Twisted provide a facility that could help me with this or do I need to interface with the OS (routing) in a different way? Or did I just use self.transport.getHost().host
incorrectly?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您是否认为通过 Twisted 一部分的 SIP 实现是否可以实现您想要的功能?
无论如何,在 Twisted 中设置 UDP 的源地址和端口的方式与在没有 Twisted 的情况下设置它们的方式非常相似。在 Twisted 中,
reactor.listenUDP(port,protocol,interface)
将 UDP 套接字绑定到特定端口和接口,并将接收到的数据报处理为您的协议。在协议内部,self.transport.write(msg, addr)
使用协议绑定的地址作为源地址向addr
发送数据报。再次阅读您的问题,我认为您唯一缺少的部分是将
interface
传递给reactor.listenUDP(...)
。Did you see if that you want to do is possible with the SIP implementation that is part of Twisted?
In any case, how you set the source address and port for UDP in Twisted is quite similar to how you set them without Twisted. In Twisted,
reactor.listenUDP(port, protocol, interface)
binds an UDP socket to a specific port and interface and handles the received datagrams to your protocol. Inside the protocol,self.transport.write(msg, addr)
sends a datagram toaddr
using the address that the protocol is bound to as source address.Reading your question again, I think the only part you were missing was passing
interface
toreactor.listenUDP(...)
.为了完整起见,我回答我自己的问题:
在尝试确定主机的源 IP 地址之前,请确保在传输上使用 connect() 。以下摘录显示了协议实现的相关部分:
For the sake of completeness I answer my own question:
Make sure you use connect() on the transport before trying to determine the host's source IP address. The following excerpt shows the relevant part of a protocol implementation:
如果您使用 UDP,则端点由以下任一方式确定:
bind()
并显式为其提供地址如果您需要更多详细信息,检查此响应。
问题是我对扭曲不太熟悉。通过快速浏览源代码,我可以看出,您可能想要使用像
tidSelectReactor
代替。这就是tndDNSDatagramProtocol
在幕后工作。如果您将
twisted
从图片中剔除,那么以下代码片段将显示正在发生的情况:如果您需要支持多个网络接口或 IPv4 和 IPv6,则获取主机名会有点棘手。如果您可以使所使用的接口可配置,则将其作为元组的第一个成员传递给
socket.bind()
即可。现在最困难的部分是在twisted 提供的抽象范围内做到这一点。不幸的是,我不能在那里提供很多帮助。我建议寻找有关如何访问底层套接字或找到将套接字信息传递到框架的方法的示例。
祝你好运。
If you are using UDP then the endpoint is determined by either:
bind()
on the socket and explicitly giving it an addressIf you want a few more details, check this response.
The problem is that I'm not that familiar with twisted. From what I can tell by a quick perusal of the source, it looks like you might want to use a reactor like
t.i.d.SelectReactor
instead. This is whatt.n.d.DNSDatagramProtocol
does under the hood.If you take
twisted
out of the picture, then the following snippet shows what is going on:Get the host name is a little trickier if you need to support multiple network interfaces or IPv4 and IPv6. If you can make the interface used configurable, then pass it in as the first member of the tuple to
socket.bind()
and you are set.Now the hard part is doing this within the confines of the abstractions that twisted provides. Unfortunately, I can't help a whole lot there. I would recommend looking for examples on how you can get access to the underlying socket or find a way to pass the socket information into the framework.
Good luck.