LINUX.ORG.RU
ФорумAdmin

Как отождествить динамический порт с статическим?

 ,


0

1

Проблема - серверу приходит соединение от клиента, он его принимает функцией accept, но в структуре клиента сервер получает лишь динамический порт клиента. Собственно, и сам сервер посылает сообщения от динамического порта. Вопрос - как получить соответствие динамических портов с реальными? Например: клиент коннектится к серверу 111 порта, в ответ приходит сокет с новым динамическим портом сервера, скажем, 22222. Сам netstat покажет нам, что наш клиент соединен с удаленным портом 111. Но как на уровне программирования получить соответствие между 22222 портом и 111 портом, ведь по факту, после соединения клиент пишет и читает в файл-сокет с портом 22222.

Собственно, и сам сервер посылает сообщения от динамического порта.

О каком «сервере» хоть речь-то? Вы не про вариации на тему ftp-data ?

anc ★★★★★ ()
Последнее исправление: anc (всего исправлений: 1)

Непонятно что Вы хотите. Как Вы будете идентифицировать клиента?
Сервер для вашей задачи должен писать в логи инфу: IP адрес клиента - порт(22222)
В реале это должно быть API у сервера (евенты, обработчики такого события),чтобы отдавать такую инфу. Так что правьте код сервера, скорее всего это не сложно кто умеет программить.
Перед созданием сокета на сервере (или после) на порт 22222 нужно вызвать функцию, которая сообщит Вам эту информацию.

Vlad-76 ★★★ ()
Последнее исправление: Vlad-76 (всего исправлений: 3)

мне кажется что нужно смотреть в сторону ip_conntrack

Michael89 ()
Ответ на: комментарий от Vlad-76

Сервер в моем случае - самый простой процесс, запустивший bind на сокет и слушающий этот сокет listen.

Я хочу следующее - удаленном компе вертится процесс, он под себя забиндил определенный порт; у меня на локалке есть информация по этому определенному порту, но когда тот удаленный процесс коннектится ко мне, становясь тем самым клиентом, он ко мне стучится с динамического порта, тем самым я не знаю, кто ко мне стучится. Что за функцию можно вызвать на динамический порт, чтобы узнать удаленный? Процедуру сокета протокола?

ip_conntrack - спасибо, посмотрю.

botcser ()
Ответ на: комментарий от botcser

Поциент похоже путается в понятиях.

Я хочу следующее - удаленном компе вертится процесс, он под себя забиндил определенный порт

Сервер???

у меня на локалке есть информация по этому определенному порту

Хорошо что она у вас есть.

он ко мне стучится с динамического порта

Это уже клиент.
Вы случайно не stupt изобретаете?

anc ★★★★★ ()
Ответ на: комментарий от anc

Постойте товарищи! Да, вы угадали, что я что-то там такое изобретаю. Да, это кажется странным, запутанным и бессмысленным. Но ведь я пришел на форум общества знатоков Linux не за тем, что бы изыскать смысла и целесообразности своего изобретения. Если начинать сначала, описывать что, почему, зачем - на это уйдет кучу моего и вашего времени и текста... Я лишь хочу локализировать проблему, выразить её в одно действие: вот первый процесс слушает порт 1 - есть? есть; вот второй процесс забиндил для себя порт 2 - есть? есть; вот второй процесс коннектится к первому - есть? есть; вот первому процессу пришел файл-сокет второго процесса с ip адресом и его динамическим портом 22222 - есть? есть; но netstat и /proc/net то видят что *.1 - *.2 соединен, а не *.1 - *.22222. Разве я где-то некорректно выразился? Подскажите, не в обиду :)

botcser ()
Ответ на: комментарий от anc

С того, что на одном ноутбуке в двух вкладках запущены процессы сервера и клиента, сервер имеет файл-сокет с портом 22222, записывает туда функцией wite(), а клиент функцие read() читает из своего файл-сокета. Я, конечно, могу, мне не трудно, выложить скрины работы и исх. коды, но мне казалась тут в части программирования всё элементарно. Не считая моего вопроса :)

я даже по памяти могу привести такой пруф отладки сис. вызова accept():

там в конце при успешном случае проверяется, передал ли процесс (сервер) структуру sockaddr, и если передал - возвращает процессу структуру о клиенте:

if (upeer_sockaddr) { if (newsock->ops->getname(newsock, (struct sockaddr *)&address, &len, 2) < 0) { err = -ECONNABORTED; goto out_fd; } err = move_addr_to_user((struct sockaddr *)&address, len, upeer_sockaddr, upeer_addrlen); ...}

Так вот, я тут отлаживал, собсно, как и в коде сервера при записи в файл-сокет таким способом:

(struct sockaddr_in *)&address->sin_port - вот тут и хранится портклиента 22222 (вместо 2)

botcser ()
Ответ на: комментарий от anc

Честно - до анализа tcpdump не опускался, хотя уже советовал друг сетевик, ему тоже понравилась моя проблема но...

Дело в том, что в пространстве ядра всё пучком, это мы видим, как netstat'ом, так и обычным cat'ом из /proc/net/tcp - порт номер 1 общается с портом номер 2 по tcp. В добавок, сам этот динамический порт 22222 не является сетевым портом, я пощупал его руками, он что-то вроде UNIX-сокетного, предназначен для локальных целей на компе. То есть, картина то в большинстве понятна, хоть и не всех она интересует изнутри - есть менеджер портов, который на каждое входящее соединение генерирует динамический исходящий порт...ну что бы один процесс-сервер мог слушать «несколько раз» listen(sock, 999). Вопрос как-раз и стоит, как на локальной машине выбить из менеджера соответствие динамического порта сетевому.

botcser ()
Ответ на: комментарий от botcser

Что-то мне подсказывает ерунду вы пишите или чего-то не так описываете. На коленке наваял нечто подобное Как отождествить динамический порт с статическим? (комментарий) все нормально, сервер повесил на 12000 клиент на 30000, как по netstat 127.0.0.1:30000 - 127.0.0.1:12000 так и по данным сервера из функции accept(s_sock, (struct sockaddr *)&addr_from, &sizefaddr);
ntohs(addr_from.sin_port) порт 30000

anc ★★★★★ ()
Ответ на: комментарий от botcser

Ой мама, перечитал и понял:

(struct sockaddr_in *)&address->sin_port - вот тут и хранится портклиента 22222 (вместо 2)

Поздравляю Шарик, ты балбес. А теперь курим документацию в части представления данных в sin_port и не только - до полного просветления. Подсказка мой пост выше.

anc ★★★★★ ()
Ответ на: комментарий от anc

Нуп и апазороился :) ибо нефих работать на больничном... а я еще чувствую, что что-то этот «дин» порт одинаковый от сессии к сессии. Извиняюсь дико! Впредь буду мучиться ещё две недельки...

В благодарность могу подкинуть еще интересную «историю» из первых рук - при запуске бинарника непосредственно из функции инициализации модуля ядра, всё работает, как по маслу; но если породить новый поток и из него вызвать тот же бин - ядро выдает errno 2 (нет такого файла). Пока что реверс показал, что это происходит из-за того, что в потомке не инициализирована переменная «текущая директория». Вопрос на засыпку - зачем кто-то добавил эту проверку в ядро...

botcser ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.