2014-10-01 2 views
-1

Я новичок в Twisted framework для python. Я играю с DNS-сервером клиента, и я хочу знать, как найти SRC_IP DNS-запроса.Python Twisted Custom DNS

Я использую следующий скрипт: http://twisted.readthedocs.org/en/latest/names/howto/custom-server.html

В частности, тот, который динамически устраняющий и хочу знать, как я могу расположен источник IP Запроса. Thanks

ответ

3

Не слишком знакомый с витой, я не знаю, является ли это лучшим способом. Я подозреваю, что то, что я предлагаю ниже, заключается не в том, что работа непосредственно на сокетах не кажется правильной, но здесь она идет.

Подкласс server.DNSServerFactory и переопределить метод handleQuery(), например:

import socket 
from twisted.internet.address import IPv4Address 

class MyDNSServerFactory(server.DNSServerFactory): 

    def handleQuery(self, message, protocol, address): 
     if protocol.transport.socket.type == socket.SOCK_STREAM: 
      self.peer_address = protocol.transport.getPeer() 
     elif protocol.transport.socket.type == socket.SOCK_DGRAM: 
      self.peer_address = IPv4Address('UDP', *address) 
     else: 
      print "Unexpected socket type %r" % protocol.transport.socket.type 

     print "Got message from : %r" % self.peer_address 
     return server.DNSServerFactory.handleQuery(self, message, protocol, address) 
. 
. 
. 

factory = MyDNSServerFactory(
    clients=[DynamicResolver(), client.Resolver(resolv='/etc/resolv.conf')] 
) 

вещи беспокоиться о:

  1. IPV6 адреса
  2. Прямое использование socket кажется коварный.
  3. Соединяет ли socket.SOCK_STREAM соединение TCP?

Есть и другие способы сделать это, например. подкласс dns.DNSDatagramProtocol и переопределить datagramReceived(self, data, addr), чтобы получить UDP-адрес клиента. Адреса клиентов TCP будут получены путем подклассификации и переопределения server.DNSServerFactory.connectionMade(self, protocol) и получения адреса peer с protocol.transport.getPeer().


Обновленный ответ сделать равный адрес доступен в DynamicResolver

Изменить MyDNSServerFactory.handleQuery() установить peer_address для резольверов, которые имеют peer_address атрибут:

class MyDNSServerFactory(server.DNSServerFactory): 

    def handleQuery(self, message, protocol, address): 
     if protocol.transport.socket.type == socket.SOCK_STREAM: 
      self.peer_address = protocol.transport.getPeer() 
     elif protocol.transport.socket.type == socket.SOCK_DGRAM: 
      self.peer_address = IPv4Address('UDP', *address) 
     else: 
      print "Unexpected socket type %r" % protocol.transport.socket.type 

     print "Got message from : %r" % self.peer_address 

     # Make peer_address available to resolvers that support that attribute 
     for resolver in self.resolver.resolvers: 
      if hasattr(resolver, 'peer_address'): 
       resolver.peer_address = self.peer_address 

     return server.DNSServerFactory.handleQuery(self, message, protocol, address) 

Добавить следующую peer_address недвижимость класса DynamicResolver :

def __init__(self): 
     self._peer_address = None 

    @property 
    def peer_address(self): 
     return self._peer_address 

    @peer_address.setter 
    def peer_address(self, value): 
     self._peer_address = value 

Теперь вы можете получить доступ к peer_address в DynamicResolver.query(), например.

def query(self, query, timeout=None): 
     print "In DynamicResolver.query(): self.peer_address = %r" % self.peer_address 
     if self._dynamicResponseRequired(query): 
      return defer.succeed(self._doDynamicResponse(query)) 
     else: 
      return defer.fail(error.DomainError()) 
+0

Большое спасибо, что выполнил эту работу. Легенда! – pjf

+0

Еще один быстрый вопрос, если я могу; Как я могу получить содержимое self.peer_address в моем классе DynamicResolver()? – pjf

+0

Yea ... Прикосновение к 'socket' делает все супер грустно. –