Найти - Пользователи
Полная версия: Asyncore клиент и исходящий IP адрес?
Начало » Python для экспертов » Asyncore клиент и исходящий IP адрес?
1
dave
Привет

Есть сервер под freebsd, к сетевому интерфейсу помимо основного IP адреса (A) привязано еще N алиасов (B1,B2,B3,BN).
Есть программа скачивающая что-то по сети и она использует asyncore. По умолчанию, программа коннектится с основного IP адреса - A. Необходимо научить программу конектится с других адресов.

Собственно я попробовал просто вызывать метод self.bind((BN, port)) и оно вроде работает (см листинг). Вопрос только в том какой указывать порт и чем это может грозить. Стоит ли указывать случайный порт >1024 или нормально всегда указывать одинаковый? У меня примерно 600 потоков работает.

Может быть кто сталкивался уже с такой задачей?
Вот тестовая программа:

import asyncore, socket

class http_client(asyncore.dispatcher):

def __init__(self, host, path):
asyncore.dispatcher.__init__(self)
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
self.bind(('1.1.1.1', 11111))
self.connect( (host, 80) )
self.buffer = 'GET '+path+' HTTP/1.0\r\n'
self.buffer += 'User-Agent: Mozilla/1.0\r\n'
self.buffer += '\r\n';

def handle_connect(self):
pass

def handle_close(self):
self.close()

def handle_read(self):
print self.recv(8192)

def writable(self):
return (len(self.buffer) > 0)

def handle_write(self):
sent = self.send(self.buffer)
self.buffer = self.buffer[sent:]

c = http_client('whatismyip.org', '/')

asyncore.loop()
j2a
Нужно настраивать не программу, а таблицу маршрутизации.
dave
j2a
Нужно настраивать не программу, а таблицу маршрутизации.
конечные адреса заранее не известны

ДА, можно сделать через nat или подмену системного вызова. Но сейчас интересует самый простой метод. Если будет достаточно добавить одну строку, то это идеально.

Release often, release fast.
redixin
ноль в качестве порта поставь, он тогда будет брать любой доступный порт >1024
dave
redixin
ноль в качестве порта поставь, он тогда будет брать любой доступный порт >1024
Вот это то что надо, жаль сам не додумался :-) Работает!

Я сейчас расскажу что я тут успел уже сделать, может будет полезно.

Добавлять вызов socket.bind( (ip,port) ) с конкретным портом не получится, если программа многопоточная. При двух одновремененых конектах будет выдавать эксцепшен EADDRINUSE.

После этого я расстроился и пошел копать NAT. Получилась такая конструкция (packet filter)
cat /etc/pf.conf.my 

nat on bge0 from 1.1.1.1/32 to any -> 2.2.2.2
pass in
pass out
где 1.1.1.1 основной адрес, а 2.2.2.2 - нужный (с которого должны уходить конекты)
Все работает за исключением того, что 1.1.1.1 более не виден снаружи (сервер натит и собственные ответы).

Итого два способа. Даже три если использовать squid. Мне кажется самый просто все-таки с socket.bind((ip,0)); ну или нат, это подходит для любых программ.

Всем спасибо! :-)
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB