LINUX.ORG.RU

/dev/net/tun <-> tcp/udp


0

1

Здравствуйте, заранее прошу прощение за тупые вопросы).
Разьясните механику.
На TCP сокет приходят данные, которые должны быть IP дейтаграммами. В дальнейшем эти дейтаграммы пишутся в /dev/net/tun. Если данные, которые пришли по TCP это НЕкорректные IP пакеты, при попытке записи оных в tun, возникает ошибка и errno устанавливается в 22(Invalid argument).

Вопросы:
1)В tun можно писать только IPv4 корректные дайтаграммы, формат которых проверяется в дальнейшем драйвером tun устройства?
2)Должен ли я проверять формат входящих по TCP данных на их корректность, жертвуя производительностью? То, что это именно IP пакет. И не позволит ли отсутсвие такой проверки провести злоумышленнику атаку по типу перполнения буфера или чего то подобного ?
3)Вдруг, кто уже расчитывал MTU для IP пакета с опциями, секономтье пож. время. Максимальный размер IP заголовка с опциями это сколько ?
4) Из TCP/UDP сокета ГАРАНТИРОВАНО за один сис.вызов read считывается ровно 1 TCP/UDP пакет или может половинка вернуться?
5)Как ioctl-ом сделать то, что делает ifconfig tun0 192.168.3.1 up? SIOCSIFADDR ??? Это будет равносильно?

Копаться в чужих исходниках прошу не посылать. Заранее спасибо. =)



Последнее исправление: koi8-r (всего исправлений: 1)

>Копаться в чужих исходниках прошу не посылать.

Они такие же чужие, как и твои!

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

3) С rfc791 разобрался, спасибо, ответ: max с опциями 60 байт.
4) А recv () ??? Можно как то отследить получение полного TCP пакета и были ли данные обрезаны из-за буыера недостаточного размера?

koi8-r
() автор топика
Ответ на: комментарий от koi8-r

По udp скорее всего ты всегда будешь получать полный пакет при условии что он вписывается в текущий mtu.

По tcp на read() ты можешь получить сколько угодно байт. Так что надо уметь склеивать фреймы.

Собственно openvpn так работает. На сколько я помню его код.

sn1ln
()
Ответ на: комментарий от koi8-r

4. Тут просто надо понимать, что есть разница между одним системным вызором чтения(я так понял из сетевухи/буфера) и между твоим read.
Например при read ты всегда будешь считывать не меньше одного пакета, просто потому что у TCP это минимальная информационная еденица(TCP не оперирует «побайтно», т.к. неполных пакетов для ТЦП не существует: либо целый пакет, либо нецелый, но тогда это сигнал к ретрансмиту)... Возможно я ошибаюсь, но на практике это выглядит обычно именно так.

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

Jetty тебя ацки глючит. Читая из TCP сокета ты получишь хер знает сколько байт, сколько прилетело столько и получишь. man recv

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

Я в курсе про то что TCP протокол типа STEAM(т.е. для него понятие «пакета» как бы не существует,в контексте передаваемых данных)... Я понимаю о чем ты :) Ну я о другом... да фиг с ним :)

Jetty ★★★★★
()

есть мнение, что туннелить IP по TCP - зло.

Adjkru ★★★★★
()

Я посмотрел исходники:
melinte
src
Здесь автор, как я понял (очень плохо читаю чужой код), после вычисления MTU, начинает писать в TUN все, что он прочитал из сокета, не обращая внимания, на то, что может прийти не целиковый IP пакет и то, что это вообще может быть не IP. Это нормально ? Спасибо всем за ваши ответы.

while (!_do_exit) {
  recvlen = rrecvfrom(_udp_fd, buf, sizeof(buf), 0, (struct sockaddr*)&cliaddr, &clilen);
  debug("SR:%04d\n", recvlen);
  if (recvlen > 0) {
    writelen = rwrite(_tun_fd, buf, recvlen); 
    debug("TW:%04d\n", writelen);
    if (writelen < 0) {
      debug("%s: rwrite() %s [%d]\n", _progname, strerror(errno), errno); 
      break; 
    }
  } else if (recvlen < 0) {
    debug("%s: rrecvfrom() %s\n", _progname, strerror(errno)); 
    break; 
  } else if (recvlen == 0) {
    break; 
  }
}
[[/code]]

koi8-r
() автор топика
Ответ на: комментарий от koi8-r

Нормально, получил пакет по UDP и целиком послал его в тунель.

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