Предыстория:

Итак, появилась необходимость дать возможность просматривать фильмы с моего сервера на телевизоре. Ну казалось бы, поднимаем DLNA, например miniDLNA и проблема решена. Так и было, пока не появилась нужда дать такую же возможность родителям, которые живут в другом месте, и ставить им там сервер или простенький nas не хотелось. Было принято решение объединить наши сети путем туннелирования трафика и дать доступ к моей фильмотеке.

Подготовка:

У родителей я уже давно поставил отличный роутер, с которым я давно работаю и доверяю — Mikrotik 951Ui 12HnD. Кто не знаком с этим великолепным маршрутизатором, советую познакомиться. Ценовая политика позволяет подобрать решения как для дома, так и для офиса. При этом получаем функционал, как у дорогих enterprise решений.

У меня в квартире так же стоял Mikrotik, лишь с одним отличием, у меня были все порты гигабитные. Я не долго думая поднял pptp туннель и тут началось…

Первые проблемы:

В отличии от классического способа передачи потокового аудио и видео сегмента данных DLNA несколько отличается. И это сразу стало понятно, после того как я посниффил трафик.

  1. Все общение между медиа сервером и телевизором происходит по протоколу HTTP
  2. Телевизор делает мультикаст рассылку SSDP пакетов на адрес 239.255.255.255.250, в которой регистрирует себя как сервис перед лицом медиа серверов.
  3. DLNA сервера при виде нового сервиса начинают обращаться к телевизору напрямую, после пары пакетов отправляет свою информацию внутри

    XML
    <?xml version="1.0" encoding="utf-8"?>
    <root xmlns="urn:schemas-upnp-org:device-1-0" 
    xmlns:dlna="urn:schemas-dlna-org:device-1-0"
    xmlns:sec="http://www.sec.co.kr/dlna">
       <specVersion>
    		<major>1</major>
    		<minor>0</minor>
       </specVersion>
       <device>
       	<dlna:X_DLNADOC xmlns:dlna="urn:schemas-dlna-org:device-1-0">DMS-1.50</dlna:X_DLNADOC>
       	<dlna:X_DLNADOC xmlns:dlna="urn:schemas-dlna-org:device-1-0">M-DMS-1.50</dlna:X_DLNADOC>
    	  <dlna:X_DLNACAP xmlns:dlna="urn:schemas-dlna-org:device-1-0">av-upload,image-upload,audio-upload</dlna:X_DLNACAP>
        <sec:ProductCap>smi,DCM10,getMediaInfo.sec,getCaptionInfo.sec</sec:ProductCap>
        <sec:X_ProductCap>smi,DCM10,getMediaInfo.sec,getCaptionInfo.sec</sec:X_ProductCap>
        <deviceType>urn:schemas-upnp-org:device:MediaServer:1</deviceType>
    		<friendlyName>[PC]DESKTOP-SBP6BH3</friendlyName>
    		<manufacturer>Samsung Electronics</manufacturer>
    		<manufacturerURL>http://www.samsung.com/sec</manufacturerURL>
    		<modelDescription>Samsung PC DMS</modelDescription>
    		<modelName>PC</modelName>
    		<modelNumber>AllShare1.0</modelNumber>
    		<modelURL>http://www.samsung.com/sec</modelURL>
    		<UDN>uuid:0d1cef00-0032-1000-8823-f46d043e5ae2</UDN>
         <sec:deviceID>H3CJEO6BEFKMU</sec:deviceID>
         <iconList>
           <icon>
             <mimetype>image/jpeg</mimetype>
             <width>48</width>
             <height>48</height>
             <depth>24</depth>
             <url>/smp_2_</url>
           </icon>
           <icon>
             <mimetype>image/jpeg</mimetype>
             <width>120</width>
             <height>120</height>
             <depth>24</depth>
             <url>/smp_3_</url>
           </icon>
           <icon>
             <mimetype>image/png</mimetype>
             <width>120</width>
             <height>120</height>
             <depth>24</depth>
             <url>/smp_4_</url>
           </icon>
           <icon>
             <mimetype>image/png</mimetype>
             <width>48</width>
             <height>48</height>
             <depth>24</depth>
             <url>/smp_5_</url>
           </icon>
         </iconList>
         <serviceList>
           <service>
             <serviceType>urn:schemas-upnp-org:service:ConnectionManager:1</serviceType>
             <serviceId>urn:upnp-org:serviceId:ConnectionManager</serviceId>
             <SCPDURL>/smp_7_</SCPDURL>
             <controlURL>/smp_8_</controlURL>
             <eventSubURL>/smp_9_</eventSubURL>
           </service>
           <service>
             <serviceType>urn:schemas-upnp-org:service:ContentDirectory:1</serviceType>
             <serviceId>urn:upnp-org:serviceId:ContentDirectory</serviceId>
             <SCPDURL>/smp_10_</SCPDURL>
             <controlURL>/smp_11_</controlURL>
             <eventSubURL>/smp_12_</eventSubURL>
           </service>
         </serviceList>
       </device>
    </root>
    


  4. После того, как вы выбрали медиа файл, который хотите прослушать\посмотреть начинается обмен по TCP, как я понимаю телевизор начинает кешировать медиа файл.



Через PPTP некоторые из этих запросов пробегали, некоторые нет. После того как я изучил дамп трафика, пришел к следующим выводам:

  • Со стороны сервера мы должны увеличить ttl трафика от DLNA сервера, ибо по умолчанию ttl=1. (Это необходимо только для SSDP трафика)
  • Установить пакет multicast на микротики, и включить PIM на интерфейсы туннеля.
  • Не забываем прописать маршруты до локальных сетей за туннелями.
  • Со стороны сервера DLNA прописываем маршрут 239.255.255.250 в качестве шлюза указываем туннельный интерфейс.

Казалось бы, все предусмотрел, я на телевизоре родителей увидел свой DLNA сервер, подключился к нему, открыл фильм, и тут я успел увидеть 2 кадра и все. Он просто отключился от сервера. Я начал заново, пробежался по всей конфигурации на обоих маршрутизаторах, грешил на фаервол. Потом опять взглянул на дамп трафика и увидел то самое..
don't fragment

И тут меня осенило! Размер пакета превышает MTU, который нам предоставляет PPTP, а фрагментировать нельзя! К сожалению в настройках miniDLNA сервера я не смог найти возможность ограничить длину пакета.

Победное решение:

В итоге самый простой IP-IP туннель предоставляет нам нужный MTU, MRU, и MSS, но сталкиваемся с проблемой динамической адресации от провайдера, если у вас на обоих концах статика, вам повезло!

Еще можно попробовать ограничить mtu на интерфейсе, к которому подключен NAS. В таком случае пакеты будут заведомо с небольшим MTU, который пролезет в любой туннель, но это может существенно нагрузить CPU.

Дополнение:

Не стоит забывать что просмотр фильмов — это нехилая нагрузка на сеть в плане ширины канала. Когда в пределах локальной сети, не страшно, а вот между сетями, когда ширину канала контролирует провайдер… В общем всем советую включить QoS, отдать приоритет своему серверу, и любым подключениям к нему, а мы можем и подождать дополнительных 30 мс для открытия странички.

Если будут пожелания, опишу детально как настраивать Mikrotik.

Статьи, которые я использовал:
ru.wikipedia.org/wiki/DLNA
ru.wikipedia.org/wiki/Maximum_transmission_unit
wiki.mikrotik.com/wiki/Manual:Routing/Multicast

Уважаемые! Если вы минусуете статью, пожалуйста, напишите в комментариях почему, и я улучшу ее!
Буду рад критике и замечаниям!

Комментарии (20)


  1. fleaump
    18.09.2015 16:44
    +1

    но сталкиваемся с проблемой динамической адресации от провайдера

    /ip cloud set ddns-enabled=true
    на обоих микротиках, и дружим уже по dns имени тоннели.

    И тут меня осенило! Размер пакета превышает MTU, который нам предоставляет PPTP, а фрагментировать нельзя! К сожалению в настройках miniDLNA сервера я не смог найти возможность ограничить длину пакета.

    Поднимает тоннель на ovpn между микротиками и получаем правильный MTU


    1. p00h
      18.09.2015 17:00

      Факультативным и очень элегантным решением было бы поднять VPLS между двумя точками и объединить их в одну «локалку». Тогда бы все вопросы, связанные с тонкостями маршрутизации отпали :)


      1. AcidVenom
        18.09.2015 21:13

        У микротика есть EoIP, почти то же самое.


        1. xyyx
          20.09.2015 08:09

          Да, я бы с него и начинал)


          1. sudoroot
            20.09.2015 12:53

            Я к сожалению не указал в статье, что искал решение подходящее для любого оборудования. В последствии к моей медиатеке подключился еще один товарищ, у него был шлюз на линуксе. EoIP есть под линукс, но его надежность сомнительна, OpenVPN (linux — mikrotik) не пробовал, а вот с IPIP все взлетело без проблем.
            Теперь буду пробовать OpenVPN. Странно, что я забыл про него =)


            1. Klukonin
              21.09.2015 11:57

              Вот, у меня это была первая мысль =)
              OpenVPN прекрасно работает под линуксом на уровне L2.


              1. AcidVenom
                21.09.2015 11:59

                Опять же, Mikrotik не умеет OVPN по UDP. И когда научится уметь, никто не знает. А это как бы не та производительность уже.


                1. fleaump
                  21.09.2015 13:14

                  И в чем проблема? Ну поставишь ты по TCP OVPN, внутри то любой трафик может ходить — UDP\GRE\IGMP\ICMP и т.д.


                  1. AcidVenom
                    21.09.2015 13:18

                    Никакой проблемы нет, только А это как бы не та производительность уже.


                    1. Klukonin
                      21.09.2015 13:54

                      Уверены?
                      А если настроить стек конкретно под ваш канал?
                      Хотя бы выбрать подходящий алгоритм согласования окна.
                      Уверяю, будет только лучше. Задержка незначительно повысится, но гемора поубваится.
                      Пропускная способность у вас какая? Тип канала?


                      1. AcidVenom
                        21.09.2015 14:37

                        Подниму мост на OVPN и отпишусь ниже.


                    1. fleaump
                      21.09.2015 13:54

                      Даже по UDP на подобном железе с openwrt роутеры не дают нормальной производительности.

                      UPD OVPN ограничен 100 мегабитами, хоть поднимай его на x86 железе, линк все равно 100мбс.


  1. sudoroot
    18.09.2015 17:09

    /ip cloud set ddns-enabled=true
    на обоих микротиках, и дружим уже по dns имени тоннели.


    IPIP туннели по DNS имени не построишь, ну если не прибегать к скриптам =)
    Если же вы про DDNS для OpenVPN — тогда да, это решение.

    Поднимает тоннель на ovpn между микротиками и получаем правильный MTU


    segment size необходимый для передачи медиаконтента равен 1448, я пробовал OpenVPN, но часть пакетов дропалась, в связи с чем я ушел на IPIP.
    Не исключаю что возможно где то я ошибся, я описал лишь собственный опыт, который привел к положительным результатам.


    1. p00h
      18.09.2015 17:20

      Пакеты внутри OVPN не могли дропаться из-за DF, потому как MTU по умолчанию 1500, что является стандартом де-факто. У IPIP, фактически, MTU меньше как минимум на еще один IP заголовок.


      1. sudoroot
        18.09.2015 17:22

        Возможно были проблемы из за старой прошивки, возможно разовые проблемы на сети провайдера, но стабильности к сожалению не было.
        На днях попробую еще разок с обновленными прошивками.


        1. p00h
          18.09.2015 17:29

          На вкус и цвет все фломастеры разные) Если работать на IPIP, зачем что-то менять?)


          1. sudoroot
            18.09.2015 17:35

            Согласен с вами!
            Но все же попробую OpenVPN, решение получится по гибче =)


  1. Ivan_83
    21.09.2015 09:19
    +1

    Телевизор выступает обычно в двух-трёх ролях:
    1. Клиента, который может ходить по всяким медиабидлиотекам
    2. Сервера/рендерера — штука которой говорят откуда брать поток и она его показывает
    3. Там ещё какой то сетевой пульт управления есть, не помню подробностей.

    Для того чтобы телек нашёл медиаблилотеку он должен получать от неё мультикаст анонсы. (тот самый SSDP)
    Сделать это можно так:
    1. Прокинуть L2 до телека (витая пара / или л2 впн через инет)
    2. Поставить локальный SSDP анонсер у себя в сети, а с той стороны в инете просто пробросить порты для HTTP.

    Запросы от телека — можно резать, просто он будет не так сразу находить медиабиблиотеку после включения, с другой стороны можно установить время SSDP анонсов на 5-10 секунд, сеть это не нагрузит.

    У меня есть свой анонсер: http://www.netlab.linkpc.net/wiki/ru:software:ssdpd:index
    чтобы им это сделать нужно:
    1. вытянуть xml файл с расшариваемого длна сервера
    2. пробросить его порт через роутер, чтобы можно было подключатся из инета
    3. поставить где то в удалённой локалке мой анонсер и скормить ему xml из п1 поправив там адреса сервера.
    Ставить можно хоть в виртуалку на виртуалбоксе с бриджованным интерфейсом. Либо самостоятельно переписать мой анонсер под винду :)

    Те можно вообще никаких л2 впн не городить.


    1. sudoroot
      21.09.2015 09:24

      Спасибо вам! К сожалению нет кармы чтобы проголосовать за ваш комментарий )


  1. sudoroot
    13.10.2015 08:53

    Решение с OpenVPN совместно с PIM не работает к моему сожалению, так как используется PPP соединение, а для работы PIM нужны link-local маршруты.