read() на НЕБЛОКИРУЮЩЕМ дескрипторе файла tun/tap получает ошибку EAGAIN

Я хочу читать IP-пакеты из неблокирующего дескриптора файла tun/tap tunfdЯ установил tunfd как неблокирующее и зарегистрируйте событие READ_EV для него в libevent.

когда событие инициируется, я сначала читаю первые 20 байтов, чтобы получить заголовок IP, а затем читаю остальные.

nr_bytes = read(tunfd, buf, 20);
...
ip_len = .... // here I get the IP length
....
nr_bytes = read(tunfd, buf+20, ip_len-20);

но для read(tunfd, buf+20, ip_len-20)Я получил ошибку EAGAIN, на самом деле должен быть полный пакет, поэтому должно быть несколько байтов, почему я получаю такую ​​ошибку?

tunfd не совместим с неблокирующим режимом или libevent?

Спасибо!

1 ответ

Решение

Чтение и запись с использованием TUN/TAP, как и чтение и запись в гнездах дейтаграмм, должны выполняться для полных пакетов. Если вы читаете в буфер, который слишком мал для размещения полного пакета, буфер будет заполнен, а остальная часть пакета будет отброшена. Для записи, если вы пишете частичный пакет, драйвер будет считать, что это полный пакет, и доставит усеченный пакет через туннельное устройство.

Поэтому, когда вы читаете устройство TUN/TAP, вы должны предоставить буфер, который по крайней мере такой же, как настроенный MTU на tun или же tap интерфейс.

Другие вопросы по тегам