Ну собственно решил я проблемы. Всё по порядку. Для начала мой провайдер по каким-то причинам не рассылает Querier ответы второй версии, хотя вещание ведётся именно на ней. Вместо этого попадаются подобные пакеты третей версии.
Почему переменная сисктл дефалт_версион не пашет? Во-первых, по моим наблюдениям по каким-то причинам сначала подключается IGMP протокол, а потом меняется переменная, по этому во время создания ИП стека версия у IGMP 3. Так что я сделал чтобы во время загрузки была вторая версия при любом раскладе. А на третью протокол умеет переключатся сам, по истечению таймер (см. RFC). Да и на любую может переключится.
Почему пропадал IPTV сигнал? Тоже оказалось всё просто. Фря шлёт пакет с приглашением и честно ждёт ответа от сервера с временем подтверждения состояния в группе. Но провайдер "какаха", он такой пакет не шлёт. По этому я вставил посылку пакета даже если ещё ожидается подключение к группе. И теперь всё работает на ура.
А вообще провайдеру бы вставить, если честно за такое. Почему работало в ХР я не знаю, видимо ей наплевать включили её в группу или нет, шлёт пакеты и всё
Вот патч, если кому интересно:
Код: Выделить всё
# diff /tmp/8.2/usr/src/sys/netinet/igmp.c /usr/src/sys/netinet/igmp.c
231a232
> static VNET_DEFINE(int, igmp_debug) = 0;
239a241
> #define V_igmp_debug VNET(igmp_debug)
250a253,255
> SYSCTL_VNET_INT(_net_inet_igmp, OID_AUTO, igmp_debug, CTLFLAG_RW,
> &VNET_NAME(igmp_debug), 0,
> "Enable debug messages");
346a352,353
> if(V_igmp_debug) printf("IGMP.C: sysctl_igmp_default_version() start \n");
>
354a362,363
> if(V_igmp_debug) printf("IGMP.C: sysctl_igmp_default_version() V_igmp_default_version=%u \n", V_igmp_default_version);
>
360a370,372
>
> if(V_igmp_debug) printf("IGMP.C: sysctl_igmp_default_version() ERROR to change! \n");
>
370a383,385
>
> if(V_igmp_debug) printf("IGMP.C: sysctl_igmp_default_version() end \n");
>
547a563,564
> if(V_igmp_debug) printf("IGMP.C: igmp_domifattach() start \n");
>
555a573,574
> if(V_igmp_debug) printf("IGMP.C: igmp_domifattach() end \n");
>
566a586,593
> int old_version_timer;
>
> old_version_timer = IGMP_RV_INIT * IGMP_QI_INIT + IGMP_QRI_INIT;
> old_version_timer *= IGMP_URI_INIT;
>
> if(V_igmp_debug) printf("IGMP.C: igi_alloc_locked() start \n");
> if(V_igmp_debug) printf("IGMP.C: igi_alloc_locked() old_version_timer=%i \n", old_version_timer);
>
574c601,602
< igi->igi_version = V_igmp_default_version;
---
> igi->igi_version = IGMP_VERSION_2;/*V_igmp_default_version;*/
> igi->igi_v2_timer = old_version_timer;
580a609,611
> if(V_igmp_debug) printf("IGMP.C: igi_allocl_locked() V_igmp_default_version = %u, for ifp ??? \n", V_igmp_default_version);
> if(V_igmp_debug) printf("IGMP.C: igi_allocl_locked() igi->igiversion = %u, for ifp ??? \n", igi->igi_version);
>
593a625,627
>
> if(V_igmp_debug) printf("IGMP.C: igi_alloc_locked() end \n");
>
715a750,751
> if(V_igmp_debug) printf("IGMP.C: igmp_input_v1_query() start \n");
>
786c822
<
---
> if(V_igmp_debug) printf("IGMP.C: igmp_input_v1_query() stop \n");
804a841,842
> if(V_igmp_debug) printf("IGMP.C: igmp_input_v2_query() start \n");
>
851a890,892
>
> if(V_igmp_debug) printf("IGMP.C: igmp_input_v2_query() is_general_query \n");
>
867a909,911
>
> if(V_igmp_debug) printf("IGMP.C: igmp_input_v2_query() Group-specific IGMPv2 query \n");
>
879a924,925
> if(V_igmp_debug) printf("IGMP.C: igmp_input_v2_query() end \n");
>
1650a1697,1698
> if(V_igmp_debug) printf("IGMP.C: igmp_fasttimo_vnet() start \n");
>
1658a1707,1710
> {
>
> if(V_igmp_debug) printf("IGMP.C: igmp_fasttimo_vnet() 1 or 2 or 3 timers are running. V_current_state_timers_running=%u V_interface_timers_running=%u V_state_change_timers_running=%u \n", V_current_state_timers_running, V_interface_timers_running ,V_state_change_timers_running);
>
1659a1712
> }
1673a1727,1729
>
> if(V_igmp_debug) printf("IGMP.C: igmp_fasttimo_vnet() igi_v3_timer=0 \n");
>
1674a1731,1733
>
> if(V_igmp_debug) printf("IGMP.C: igmp_fasttimo_vnet() igmp_v3_dispatch_general_query() now running \n");
>
1719a1779,1781
>
> if(V_igmp_debug) printf("IGMP.C: igmp_fasttimo_vnet() igmp_v1v2_process_timer() now running; IGMPv=%u \n", igi->igi_version);
>
1723a1786,1788
>
> if(V_igmp_debug) printf("IGMP.C: igmp_fasttimo_vnet() igmp_v3_process_group_timers() now running \n");
>
1750a1816,1819
>
> if(V_igmp_debug) printf("IGMP.C: igmp_fasttimo_vnet() end \n");
>
>
1763a1833,1834
> if(V_igmp_debug) printf("IGMP.C: igmp_v1v2_process_group_timer() start \n");
>
1767a1839,1841
>
> if(V_igmp_debug) printf("IGMP.C: igmp_v1v2_process_group_timer() inm_timer=0. Interface name=%s\n", inm->inm_ifp->if_xname);
>
1769a1844,1846
>
> if(V_igmp_debug) printf("IGMP.C: igmp_v1v2_process_group_timer() --inm_timer=0. Interface name=%s\n", inm->inm_ifp->if_xname);
>
1771a1849,1851
>
> if(V_igmp_debug) printf("IGMP.C: igmp_v1v2_process_group_timer() V_current_state_timers_running=1. inm->inm_timer=%u. Interface name=%s\n", inm->inm_timer, inm->inm_ifp->if_xname);
>
1775a1856,1857
> if(V_igmp_debug) printf("IGMP.C: igmp_v1v2_process_group_timer() switch of inm->inm_state start. inm_state=%u. Interface name=%s\n", inm->inm_state, inm->inm_ifp->if_xname);
>
1779d1860
< case IGMP_IDLE_MEMBER:
1783c1864,1882
< break;
---
> break;
> case IGMP_IDLE_MEMBER:
> /*
> * If your ISP is the same shit as me, then there is the possibility
> * that the Querier will not send the answers that you join the group,
> * and in fact in this package contains a timer for the confirmation
> * of the group. According to this here, when you exit the timer is
> * still sent to report on membership. Although there is an option that
> * your network is simply no Querier.
> */
> if (inm->inm_state == IGMP_IDLE_MEMBER) {
> inm->inm_state = IGMP_REPORTING_MEMBER;
> inm->inm_timer = IGMP_RANDOM_DELAY(IGMP_V1V2_MAX_RI * 10); /* Max 10 sec RFC 1112*/
> V_current_state_timers_running = 1;
> if(V_igmp_debug) printf("IGMP.C: igmp_v1v2_process_group_timer() MUST BE 2! inm_state=%u", inm->inm_state);
> if(V_igmp_debug) printf("IGMP.C: igmp_v1v2_process_group_timer() Your ISP shit or in your network is simply no Querier, but REPORT send by me \n");
>
> }
> else break;
1785a1885,1886
> if(V_igmp_debug) printf("IGMP.C: igmp_v1v2_process_group_timer() IGMP_v1_v2_HOST_MEMBERSHIP_REPORT \n");
>
1797a1899,1901
>
> if(V_igmp_debug) printf("IGMP.C: igmp_v1v2_proc_grp_timers() end \n");
>
1812a1917,1918
> if(V_igmp_debug) printf("IGMP.C: igmp_v3_process_group_timers() start \n");
>
1845a1952,1953
> if(V_igmp_debug) printf("IGMP.C: igmp_v3_process_group_timers() switch of inm_state start \n");
>
1862a1971,1973
>
> if(V_igmp_debug) printf("IGMP.C: igmp_v3_process_group_timers() IGMP_REPORTING_MEMBER \n");
>
1915a2027,2029
>
> if(V_igmp_debug) printf("IGMP.C: igmp_v3_process_group_timers() end \n");
>
1956a2071,2072
> if(V_igmp_debug) printf("IGMP.C: igmp_set_version() start \n");
>
1969a2086,2087
> if(V_igmp_debug) printf("IGMP.C: igmp_set_version() old_timer=%i \n", old_version_timer);
>
1981a2100,2102
>
> if(V_igmp_debug) printf("IGMP.C: igmp_set_version() IGMP_VERSION=2. And now igmp_v3_cancel_link_timers starts \n");
>
1989a2111,2113
>
> if(V_igmp_debug) printf("IGMP.C: igmp_set_version() end \n");
>
2089a2214,2215
> if(V_igmp_debug) printf("IGMP.C: igmp_v1v2_process_querier_timers() start \n");
>
2096c2222,2223
< if (igi->igi_version != IGMP_VERSION_3) {
---
> /* if (igi->igi_version != IGMP_VERSION_3) {*/
> if ((igi->igi_version != IGMP_VERSION_3) && (V_igmp_default_version == IGMP_VERSION_3)) {
2100a2228,2230
>
> if(V_igmp_debug) printf("IGMP.C: igmp_v1v2_process_querier_timers() transition to IGMPv3 on %s \n", igi->igi_ifp->if_xname);
>
2119c2249,2256
< --igi->igi_v2_timer;
---
> if (igi->igi_v2_timer > 0) {
>
> --igi->igi_v2_timer;
>
> if(V_igmp_debug) printf("IGMP.C: igmp_v1v2_process_querier_timers() v2_timer-1 on %s\n", igi->igi_ifp->if_xname);
> }
> else if(V_igmp_debug) printf("IGMP.C: igmp_v1v2_process_querier_timers() v2_timer=0 on %s\n", igi->igi_ifp->if_xname);
>
2153a2291,2293
>
> if(V_igmp_debug) printf("IGMP.C: igmp_v1v2_process_querier_timers() end \n");
>
2197a2338,2340
>
> if(V_igmp_debug) printf("IGMP.C: igmp_v1v2_queue_report() start \n");
>
2248a2392,2393
> if(V_igmp_debug) printf("IGMP.C: igmp_v1v2_queue_report() end \n");
>
2347a2493,2495
> if(V_igmp_debug) printf("IGMP.C: igmp_initial_join() start \n");
>
>
2377a2526,2528
>
> if(V_igmp_debug) printf("IGMP.C: igmp_initial_join() Attention! inm_state=IGMP_SILENT_MEMBER \n");
>
2393a2545,2547
>
> if(V_igmp_debug) printf("IGMP.C: igmp_initial_join() IGMPv1v2 join on %s\n", inm->inm_ifp->if_xname);
>
2399a2554,2556
>
> if(V_igmp_debug) printf("IGMP.C: igmp_initial_join() error=igmp_v1v2_queue_report()=0 \n");
>
2402a2560
> if(V_igmp_debug) printf("IGMP.C: igmp_initial_join() error=0 inm->inm_timer=%u, V_current_state_timers_running=%u. Interface %s.\n", inm->inm_timer, V_current_state_timers_running, inm->inm_ifp->if_xname);
2462a2621,2622
> if(V_igmp_debug) printf("IGMP.C: igmp_initial_join() end \n");
>