У меня есть Разветвляющихся HTTP прокси реализованный на моем Ubuntu 14.04 x86_64 со следующей схемой (Я сообщаю существенный код и псевдокод просто, чтобы показать концепцию):Как видеть заголовки TCP, IP в моем HTTP-прокси?
socketClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)
;bind(socketClient,(struct sockaddr*)&addr, sizeof(addr))
;listen(socketClient, 50)
;newSocket = accept(socketClient, (struct sockaddr*)&cliAddr, sizeof(cliAddr))
;- получить запрос от клиента, проанализировать его для разрешения запрошенного имени хоста в IP-адресе;
fork()
, открыть соединение с удаленным сервером и обработать запрос;- дочерний процесс: если это запрос
GET
, отправьте исходный запрос на сервер и пока сервер отправляет данные, отправляет данные с сервера на клиент; - дочерний процесс: else, если это
CONNECT
запрос, отправьте строку200 ok
клиенту и опросите как дескриптор дескриптора клиента, так и дескриптор дескриптора сервера сselect()
; если я прочитаю данные из сокета сервера, отправьте эти данные клиенту; иначе, если я прочитаю данные из клиентского сокета, отправьте эти данные на сервер.
Хорошо, что этот прокси работает, плохо то, что теперь я должен собирать статистику; это плохо, потому что я работаю на уровне, где я не могу получить интересующие меня данные. Меня не интересует полезная нагрузка, мне просто нужно проверить заголовки IP и TCP на флагах, которые меня волнуют.
Например, меня интересует:
- связи трекинга;
- количество отправленных и полученных пакетов.
Что касается первого, я бы проверил в заголовке TCP флаг SYN, SYN/ACK, а затем последний ACK; что касается второго, я бы просто сделал +1 на счетчике каждый раз, когда char buffer[1500]
заполняется данными, когда я send()
или recv()
полный пакет.
Я понял, что это неверно: SOCK_STREAM
не имеет понятия пакета, это просто непрерывный поток байтов! char buffer[1500]
Я использую в точках 7. и 8. имеет полезную статистику, я могу установить ее емкость 4096 байт, и все же я не мог отслеживать переданные или полученные TCP-пакеты, поскольку TCP имеет сегменты, а не пакеты ,
Я не смог разобрать char buffer[]
, ища флаг SYN в заголовке TCP, потому что заголовки IP и TCP удалены из заголовка (из-за уровня, над которым я работаю, указанного с флагом IPPROTO_TCP
), и, если я хорошо понимал, char buffer[]
содержит только полезную нагрузку, бесполезную для меня.
Так что, если я работаю на слишком высоком уровне, я должен идти ниже: как только я увидел простой raw
сокетов сниффер, где unsigned char buffer[65535]
низвержен на struct ethhdr, iphdt, tcphdr
и он мог видеть все флаги всех заголовки, все статистические данные, которые меня интересуют!
После радости разочарование: начиная с raw
сокеты работают на низком уровне, у них нет некоторых понятий, жизненно важных для моего прокси; raw
розетки не могут bind
, listen
и accept
; мой прокси-сервер прослушивает фиксированный порт, но raw
сокеты не знают, что такое порт, он относится к уровню TCP и bind
к указанному интерфейсу с setsockopt
.
Так что, если я бы socket(PF_INET, SOCK_RAW, ntohs(ETH_P_ALL))
я должен быть в состоянии разобрать буфер, где я recv()
и send()
на .7 и .8, но я должен использовать recvfrom()
и sendto()
... но все это звучит довольно грязно, и envolves хороший рефакторинг моего кода.
Как сохранить целостность структуры моего прокси-сервера (bind, listen, accept
на фиксированный порт и интерфейс) и увеличить мою линию видимости для заголовков IP и TCP?
платформа ......? – pm100
Я отредактирую вопрос для получения более подробной информации. – elmazzun
Очень маловероятно, что вы получаете UDP с прокси-сервером HTTP вообще. –