После запроса об этой же проблеме на форуме Linux и некоторого тестирования ошибок у меня есть следующая информация, которая кажется относящейся к моей проблеме:
Я создаю приложение, которое перенаправляет входящие пакетыловушка сети ядра к прокси в пользовательском пространстве, которая считывает данные из сокета tcp и затем отправляет их в исходное место назначения.Когда пакет входит, я изменяю адреса назначения skb на адреса моего прокси-сервера tcp, а когда он уходит, я меняю адреса источника, так что связь будет проходить прозрачно.
Я столкнулся со следующей проблемой:
Когда вводятся большие объемы данных, они без проблем достигают прокси.
Однако при отправке данных в исходное место назначения, если я отправляю достаточно большой объем данных, система зависает.Отладка Caveman показала, что skb
является нелинейным только тогда, когда он покидает прокси-сервер, и без вызова skb_linearize
контрольная сумма не вычисляется успешно.
Я сам не выделяю никаких данных в ядре, когда данныезавершает работу и, похоже, не содержит ошибок памяти в моем собственном коде, поэтому я пришел к выводу, что с большой вероятностью проблема связана с моим использованием skb_linearize
функции или с тем, как я вычисляю контрольную сумму в целом:
void fixChecksum(struct sk_buff *skb)
{
if(skb_is_nonlinear(skb))
{
skb_linearize(skb);
}
struct iphdr *ip_header = ip_hdr(skb);
struct tcphdr *tcp_header = (struct tcphdr*)(skb_network_header(skb) + ip_hdrlen(skb));
int tcplen = (skb->len - ((ip_header->ihl )<< 2));
tcp_header->check=0;
tcp_header->check = tcp_v4_check(tcplen, ip_header->saddr, ip_header->daddr,csum_partial((char*)tcp_header, tcplen,0));
skb->ip_summed = CHECKSUM_NONE; //stop offloading
ip_header->check = 0;
ip_header->check = ip_fast_csum((u8 *)ip_header, ip_header->ihl);
}
Я подозреваю, что данные, которые я передаю, каким-то образом остаются в ядре, и после достаточно большого количества ядра заканчивается и система зависает.Однако я не вижу, что здесь может быть не так.Я также попытался изменить skb_linearize
на skb_linearize_cow
, что не помогло.
Возможно ли, что обработанные skbs на хуке LOCAL_OUT
не освобождаются после их обработки?
Моя версия ядра 3.2