# Internet Group Management Protocol

L'Internet Group Management Protocol è un protocollo per la gestione dei gruppi multicast. Costituisce il mezzo per un host di informare il router ad esso collegato che un'applicazione che funziona nell'host vuole unirsi a uno specifico gruppo multicast. IGMP opera fra un host e il router ad esso collegato direttamente, per coordinare i router multicast invece è richiesto un altro protocollo, affinché i datagrammi multicast possano essere instradati alle loro destinazioni finali. Questa funzionalità è svolta da algoritmi di instradamento multicast dello strato della rete: PIM, DVMRP, MOSPF. Il protocollo attualmente è alla terza versione (IGMPv3) che ha introdotto un sostanziale cambiamento rispetto alle versioni precedenti per quanto riguarda il modello del multicast in Internet: infatti ora IGMP è compatibile col modello Source Specific Multicast (SSM), cioè gli host non sono più obbligati a ricevere dall'intero gruppo ma possono selezionare un sottoinsieme di sorgenti da cui ricevere. Il protocollo nella sua versione più recente è definito nell'RFC 3376.

## Indirizzi di gruppo

Un indirizzo di gruppo o multicast è un indirizzo IP di classe D di 32 bit (Ipv4) o multicast di 128 bit (Ipv6). Nel caso Ipv4 i primi 4 bit del primo ottetto sono fissati e corrispondono al pattern 1110 mentre i restanti 28 bit costituiscono il Multicast Group ID, quindi tutti questi indirizzi sono nel range 224.0.0.0 – 239.255.255.255. Il corrispondente Ethernet/MAC Address (48 bit) usa una parte dell'indirizzo multicast IP e si ottiene in questo modo:
* Il primo ottetto è statico e posto a 00000001;
* Il secondo ottetto è statico e posto 00000000;
* Il terzo ottetto è statico e posto a 01011110;
* La parte restante è composta da uno 0 seguito dai 23 low-order bit del multicast address.
Per permettere ad un host di configurare la propria architettura per riconoscere come locale un indirizzo multicast i linguaggi di programmazione mettono a disposizione delle primitive, come la SetSockOpt in C, che quando invocate scatenano nell'architettura la configurazione su un'interfaccia di livello 2 dell'indirizzo Ethernet costruito. Del range di indirizzi quelli realmente disponibili per applicazioni multicast sono in realtà un sottoinsieme:
* 224.0.0.0 è riservato;
* Gli IP da 224.0.0.1 a 224.0.0.255 sono riservati per routing e protocolli di basso livello per discovery/maintenance della topologia di rete. Ad esempio 224.0.0.1 indirizza tutto il gruppo di host nella subnet, 224.0.0.2 indirizza tutto il gruppo di router nella subnet, 224.0.1.1 è riservato per il protocollo NTP;
* Gli IP da 224.0.1.0 a 238.255.255.255 sono dinamicamente assegnati ad applicazioni multicast. Di questi gli indirizzi da 232.0.0.0 a 232.255.255.255 sono riservati per Source Specific Multicast;
* Gli IP da 239.0.0.0 a 239.255.255.255 sono riservati per scopi amministrativi.
Chi vuole annunciare l'inizio di una sessione multicast lo fa tramite Session Directory (SDR) su opportuni server, specificando la data e l'ora d'inizio e il contenuto della trasmissione. Gli host interessati a ricevere la trasmissione multicast attraverso opportuni tool SDR possono ricavare l'indirizzo al quale la/le sorgente/i invieranno il proprio traffico e provvedono a configurarsi per accettare il traffico da quell'indirizzo.

## Overview protocollo

Il funzionamento del IGMP si basa su un modulo presente negli host e su un modulo presente nei router. Il primo svolge tutte le attività richieste ad un host che partecipa alla sessione multicast: gestione del proprio stato di ricezione, risposta alle query inviate dal Designated Router (DR) per quella LAN, invio triggered di report al DR quando lo stato di ricezione di un'interfaccia cambia per informarlo del nuovo stato di ricezione. Il secondo a bordo di un router IGMP svolge, per ogni gruppo desiderato, funzionalità di gestione e tracciamento dello stato di ricezione degli host della LAN di cui è DR e regola l'inoltro dei pacchetti provenienti dalla struttura di instradamento sulla LAN, se è contemporaneamente DR IGMP e DR per il protocollo di routing usato, altrimenti suggerisce le regole di inoltro al router che è il DR per il protocollo di routing (in genere quindi un router deve avere a bordo sia il modulo per la membership che per il routing).

## Protocollo lato Host

Quando un'applicazione in un host desidera ricevere da un indirizzo multicast, provvede a configurare un'interfaccia di livello 2 che accetterà ed eseguirà la delivery del traffico ricevuto da quell'indirizzo. A questo scopo, lo standard definisce una primitiva indipendente dal linguaggio (che dovrà essere implementata nei specifici linguaggi di programmazione) di nome IPMulticastListen. I suoi parametri sono:
* Socket id con cui l'applicazione usa la rete;
* Interfaccia dalla quale l'applicazione vuole ricevere;
* Indirizzo multicast dal quale l'applicazione vuole ricevere;
* Source list che specifica da quali sorgenti ricevere, in accordo al modello Source Specific Multicast (da IGMPv3);
* Un filtro che si applica alla Source list: include se l'applicazione vuole ricevere solo dalle sorgenti specificate nella lista, exclude se vuole ricevere da tutte tranne quelle specificate nella lista.
Questa quintupla va a definire un socket record. La Source list può essere anche vuota: se il filtro associato è include, include significa leave (uscita) dal gruppo; se è exclude, exclude significa join (aggancio) all'intero gruppo. Prima di IGMPv3 data l'assenza del modello SSM (e quindi della Source list) queste due espressioni erano le uniche ammesse. Non è ammesso specificare per uno stesso record i due filtri contemporaneamente perché l'interfaccia di rete fa filtering e gestisce al massimo un record per ogni indirizzo multicast. Uno degli scopi di IGMP è sintetizzare il più possibile le informazioni di stato associate ad un gruppo, perciò mentre a livello 4 si usa il socket record a livello 2 si fa uso dell'interface record, che è una quartupla ottenuta dal socket record al quale si toglie il socket id. In questo modo i livelli bassi della rete hanno associato meno informazione di stato e possono lavorare più velocemente, lasciando il lavoro di demultiplexing del traffico ricevuto ai livelli superiori. Un problema di avere un solo record per ogni gruppo è che l'host deve fare merge delle direttive che arrivano dalle (possibili) diverse applicazioni, nel momento in cui queste applicazioni desiderano ricevere dalla stessa interfaccia. Come esempio, si supponga di avere due applicazioni che sono in ascolto sulla stessa interfaccia per lo stesso gruppo con questi record:
A1: <s1, ifc_i, group_address, include, {a,b,c} > A2: <s2, ifc_i, group_address, include, {b,c,d} >
L'interfaccia ifc_i sintetizza tenendo conto che se tutti i record hanno filtro include per l'additività di quest'ultimo (e per soddisfare tutte le richieste) il filtro risultante sarà include e la Source list sarà l'unione delle Source list:
< group_address, include, {a,b,c,d} >
Se invece almeno uno dei filtri è exclude, lo standard suggerisce che il filtro risultante dovrà essere exclude e la Source list sarà data dall'intersezione delle liste exclude meno le sorgenti che compaiono nelle liste include. Ad esempio se 3 applicazioni hanno associato i seguenti record:
A1: <s1, ifc_i, group_address, exclude, {a,b,c,d} > A2: <s2, ifc_i, group_address, exclude, {b,c,d,e} > A2: <s3, ifc_i, group_address, include, {d,e,f} >
l'interfaccia ifc_i ricorda come filtro exclude e la lista di sorgenti sarà data da ({a,b,c,d} ∩ {b,c,d,e}) - {d,e,f} = {b,c,d} - {d,e,f} = {b,c}.

### Messaggi scambiati: Query

Le query IGMP sono il modo con cui il Designated Router viene a conoscenza e rimane informato sullo stato di membership degli host nella LAN. Si differenziano tre tipi di query:
* General Query;
* Group Specific Query;
* Group And Source Specific Query.
Tutte le query sono inviate in un pacchetto IP con campo Protocol = 2 (IGMP) e TTL = 1 (diffusione locale su LAN). Le General Query sono inviate periodicamente e rivolte a tutti gli host. Permettono al DR di rinfrescare il suo stato sulla situazione attuale di membership; le risposte a tali query richiedono poco processing da parte del router e non causano, in genere, un aggiornamento dello stato che esso mantiene per ogni gruppo. L'indirizzo al quale sono inviate è 224.0.0.1 (all-hosts group). Le Group Specific Query e le Group And Source Specific Query sono rivolte solo agli host che ricevono dall'indirizzo multicast specificato e sono inviate dal router a seguito di un aggiornamento dello stato per quello specifico gruppo per capire se c'è ancora qualche host interessato a ricevere dal gruppo (primo caso) o da specifiche sorgenti per quel gruppo (secondo caso). L'indirizzo di destinazione è quello del gruppo multicast interrogato. Una query IGMP è composta da questi campi:
* Type = 0x11 identifica che questo messaggio è una query IGMP;
* Max Resp Code (MRC) è un valore su 7 bit (tra 0 e 127) che viene usato dagli host per ricavare un Max Response Time usato per desincronizzare le loro risposte, al fine di evitare collisioni sul mezzo broadcast e il problema dell'ack-implosion lato router. Il Max Response Time è ricavato in questo modo:
IF (MRC < 128) THEN Response Time = MRC; ELSE { MRC = [1 <exp> <mantissa> ]; Response Time = (mant | 0x10) << (exp +3); } ;
* Checksum è usato per ricoverare eventuali errori avvenuti durante la trasmissione;
* Group Address è non nullo solo nelle Group Specific Query e Group And Source Specific Query e rappresenta l'indirizzo interrogato;
* Resv è un insieme di bit riservato ad uso futuro;
* Il flag S (Suppress Router-Side Processing) se settato indica ai router riceventi di sopprimere i normali aggiornamenti del timer;
* QRV (Querier's Robustness Variable) rappresenta la Robustness Variable: quante volte gli host devono inviare un cosiddetto unsolicited report (notifica del cambio di stato di un'interfaccia) per garantire che il router lo riceva senza perdite dovute a collisioni. È un valore rinfrescato dal router ogni volta che invia una query, cosa che il router può fare in quanto i router attaccati a una LAN sono in genere gateway, apparati più evoluti di un comune router che ricevendo i segnali di jam dovuti a collisioni possono fare una stima di quanto traffico è presente sulla LAN;
* QQIC (Querier's Query Interval Code) è l'intervallo tra invii di General Query, rappresentato come Max Response Code. Dà un'indicazione agli altri router (se ce ne sono) di quando farsi sentire, perché se passato questo tempo non vedono arrivare alcuna query probabilmente è successo qualcosa al DR corrente;
* Number Of Sources (N) indica il numero di sorgenti in una Group And Source Specific Query;
* Source Address [1], ..... , Source Address [N] specificano ognuno l'indirizzo unicast IP di una sorgente per il gruppo indicato nel campo Group Address. La lista di sorgenti è non vuota solo nelle Group And Source Specific Query.

### Messaggi scambiati: Report

I report IGMP sono messaggi inviati dagli host al DR all'indirizzo 224.0.0.22 (IGMPv3_capable routers). Possono essere di due tipi:
* Report inviati in risposta ad una General Query;
* Unsolicited Report, inviati quando si verifica un cambio di stato in un'interfaccia. Sono unsolicited perché l'invio non è sollecitato da una query del DR.
Un report IGMP ha i seguenti campi:
* Type = 0x22 identifica che questo messaggio è un report IGMP;
* Reserved: riservato ad uso futuro;
* Checksum è usato per ricoverare eventuali errori avvenuti durante la trasmissione;
* Number of Group Records (M): numero di gruppi per cui l'host sta riportando lo stato di ricezione;
* Group Record [1], ….. , Group Record [M]: ognuno di questi campi è a sua volta un messaggio che dettaglia lo stato di ricezione per quel gruppo.
Mentre la risposta ad una General Query contiene un Group Record per ogni gruppo da cui l'host sta attualmente ricevendo, la risposta agli altri tipi di query contiene solo il Group Record relativo al gruppo interrogato. Ogni Group Record comprende i seguenti campi:
* Record Type dice che tipo di informazione contiene il record;
* Aux Data Len indica la lunghezza delle informazioni ausiliarie presenti nel messaggio;
* Number of Sources (N) indica il numero di sorgenti per il gruppo specificato;
* Multicast Address specifica l'indirizzo del gruppo cui questo Group Record si riferisce;
* Source Address [1], ...., Source Address [N] specificano ognuno l'indirizzo IP unicast di una sorgente che appartiene al gruppo indicato nel campo Multicast Address. La lista di sorgenti è quella dell'interfaccia;
* Auxiliary Data contiene informazioni ausiliarie relative al gruppo se avanza spazio, tuttavia queste informazioni non dovrebbero mai essere presenti.
Il campo Record Type è diverso a seconda del tipo di report. Se esso è una risposta ad una General Query è di tipo Current_state ed è uno dei due Mode_Is_Include o Mode_Is_Exclude. Altrimenti il report notifica un cambio di stato di un'interfaccia e può essere:
* Filter_Mode_Change: uno tra Change_To_Include_Mode o Change_To_Exclude_Mode;
* Source_List_Change: uno tra Allow_New_Sources o Block_Old_Sources.
Tutti i messaggi IGMP devono stare in un pacchetto IP. Se il numero di sorgenti (che determina la lunghezza del messaggio) eccede la dimensione del pacchetto è necessario frammentare i report. In questo caso il comportamento è diverso a seconda del contenuto del campo Record_Type. Se è uno tra Mode_Is_Include, Change_To_Include_Mode oppure Source_List_Change allora è possibile frammentare su più pacchetti IP successivi, altrimenti (causa non additività del filtro exclude) l'host invia un solo pacchetto in cui inserisce più sorgenti possibili e le altre non vengono indicate. Lo standard suggerisce che le sorgenti indicate dovrebbero essere sempre le stesse nei report successivi. Dato che il filtro è exclude, questo significa che alcune sorgenti che in realtà non dovrebbero passare invece passano: l'ottica del multicast è che si preferisce far passare qualcosa in più in situazioni di incertezza piuttosto di correre il rischio di scontentare utenti paganti.

### Cambio di stato dell'interfaccia

A seguito di direttive IPMulticastListen provenienti dai livelli superiori lo stato di ricezione per un particolare gruppo su una data interfaccia può cambiare. Come conseguenza, l'interfaccia interessata deve inviare il più prontamente possibile un unsolicited report al DR corrente per informarlo del cambiamento. Il DR provvederà quindi ad aggiornare il proprio stato per quel gruppo. È previsto che questi report vengano inviati per robustezza un certo numero di volte, in numero definito dal campo QRV presente nelle query inviate dal DR, ad intervalli random tra 0 e Unsolicited Report Interval (quest'ultimo è un parametro configurabile dall'amministratore di rete). La tabella seguente riporta i cambi di stato che possono occorrere su un'interfaccia. Qui A e B rappresentano insiemi di sorgenti piuttosto che singole sorgenti.
| Vecchio Stato | Nuovo stato | Report inviato/i |
| Include (A) | Include (B) | Allow_New (B-A) ; Block_Old (A-B) |
| Exclude (A) | Exclude (B) | Allow_New (A-B) ; Block_Old (B-A) |
| Include (A) | Exclude (B) | Change_To_Exclude (B) |
| Exclude (A) | Include (B) | Change_To_Include (B) |

### Procedura di risposta ad una Query

Quando un host riceve una query dal DR esegue una routine per schedulare una risposta che tiene conto di eventuali query pendenti (ricevute precedentemente e in attesa di risposta). L'host cerca di condensare in un unico report le varie query pendenti, quando possibile. La seguente procedura (in pseudo-codice) è invocata dall'host:

## Protocollo lato Router

Analogamente agli host un router IGMP cerca di sintetizzare il più possibile lo stato di ricezione per ogni gruppo da cui gli host sono interessati a ricevere. La struttura mantenuta per ogni gruppo è una quadrupla così definita:
< multicast_address, group_timer, filter_mode, {source_record} >
dove:
* multicast_address è l'indirizzo multicast del gruppo;
* group_timer è un timer associato all'intero gruppo, rinfrescato ogni volta che riceve un report;
* {source_record} è un insieme di coppie di valori < source_address, source_timer >, dove source_timer è rinfrescato ogni volta che la sorgente compare in un report.
Il group_timer è stato pensato per permettere al DR del protocollo di routing di tagliare traffico non più desiderato da alcun host quando il filtro corrente è exclude e il timer scade. Infatti exclude fa passare tutto il traffico tranne quello proveniente dalle sorgenti specificate nella lista: se il timer scade significa che nessun host in stato exclude ha provveduto a rinfrescare il proprio stato di ricezione (altrimenti almeno uno avrebbe inviato un report) e quindi con molta probabilità gli host non sono più interessati a ricevere dal gruppo. Allora il DR converte il filtro in include con le sole sorgenti che hanno associato un timer > 0, restringendo la quantità di traffico che viene inoltrata sulla LAN. Se ora anche per le sorgenti rimaste il DR vede scadere il timer, allora può dedurre con certezza che nessuno è più interessato a ricevere dal gruppo e può cancellare il record associato.

### Struttura filtri Include ed Exclude

Il filtro Include ha associato una sola lista di sorgenti con timer > 0. Se per una sorgente il timer scade, essa può essere cancellata dal filtro. Se anche l'ultima sorgente rimasta è tale che source_timer = 0, il filtro include che ne deriva equivale a una leave dal gruppo e il record per il gruppo può essere cancellato. Il filtro exclude ha invece associato due liste: una che corrisponde alle sorgenti con timer > 0 e una a quelle con timer = 0; la sua forma generale è quindi Exclude (X,Y). La prima lista è quella delle sorgenti tentative, per le quali il router a seguito di un aggiornamento del record per il gruppo (che deriva dalla ricezione di un unsolicited report) invia una Group Specific o Group And Source Specific Query al gruppo per verificare se c'è qualche host che desidera ancora ricevere da quelle sorgenti. In attesa di ricevere una risposta, fa passare il traffico proveniente da quelle sorgenti. Se entro un certo tempo non riceve risposta, il router le blocca ma non ne cancella i record perché qualcuno le voleva e possono tornare abilitate, altrimenti le toglie dal filtro lasciandole passare. La seconda lista comprende le sorgenti con timer associato = 0 che sono bloccate. La tabella che segue mostra le regole di inoltro suggerite da IGMP quando il router riceve un pacchetto multicast da una specifica sorgente.
| Filtro | Source Timer | Azione |
| Include | > 0 | Inoltrare |
| Include | == 0 | Non inoltrare – Cancellare sorgente |
| Include | Nessuna sorgente | Non inoltrare: Leave dal gruppo |
| Exclude | > 0 | Inoltrare |
| Exclude | == 0 | Non inoltrare |
| Exclude | Nessuna sorgente | Inoltrare: Join all'intero gruppo |

### Aggiornamento informazioni di stato

Ogni volta che il DR riceve un report da un host provvede ad aggiornare il proprio stato per ogni gruppo che compare nel report con l'obiettivo di mantenere uno stato il più sintetico ma preciso possibile dello stato di membership nella LAN. Gli aggiornamenti in genere richiedono l'invio da parte del router di Group Specific/Group And Source Specific Query per verificare se, a seguito del volere di un host di cancellare alcune sorgenti, esistono altri host che vogliono invece ancora ricevere da esse. Se il filtro attuale tenuto dal router per il gruppo è Include i possibili casi sono i seguenti, dove A e B ancora una volta indicano gruppi di sorgenti.
| Vecchio Stato | Report ricevuto | Nuovo stato | Azioni richieste |
| Include (A) | Mode_Is_Include (B) | Include (A+B) | |
| Include (A) | Mode_Is_Exclude (B) | Exclude (A∩B, B-A) | Cancellare (A-B); Inviare Q(G, A∩B) |
| Include (A) | Change_To_Include (B) | Include (A+B) | Inviare Q(G, A-B) |
| Include (A) | Change_To_Exclude (B) | Exclude (A∩B, B-A) | Cancellare (A-B); Inviare Q(G, A∩B) |
| Include (A) | Allow_New (B) | Include (A+B) | |
| Include (A) | Block_Old (B) | Include (A) | Inviare Q(G, A∩B) |
Valgono le seguenti regole:
* quando il filtro è Include e il report ricevuto ha filtro Include il router non dovrebbe mai cambiare il filtro in Exclude;
* quando il filtro è Include e il report ricevuto ha filtro Exclude il router deve cambiare il filtro in Exclude.
Se il filtro corrente è Exclude si hanno i seguenti casi:
| Vecchio Stato | Report ricevuto | Nuovo stato | Azioni richieste |
| Exclude (X, Y) | Mode_Is_Include (A) | Exclude (X+A, Y-A) | |
| Exclude (X, Y) | Mode_Is_Exclude (A) | Exclude (A-Y, Y∩A) | Cancellare (X-A) ; Cancellare (Y-A) |
| Exclude (X, Y) | Change_To_Include (A) | Exclude (X+A, Y-A) | Inviare Q(G, X-A) ; Inviare Q(G) |
| Exclude (X, Y) | Change_To_Exclude (A) | Exclude (A-Y, Y∩A) | Cancellare (X-A) ; Cancellare (Y-A) ; Inviare Q(G, A-Y) |
| Exclude (X, Y) | Allow_New (A) | Exclude (X+A, Y-A) | |
| Exclude (X, Y) | Block_Old (A) | Exclude (X + (A-Y)), Y) | Inviare Q(G, A-Y) |
L'invio delle query avviene per robustezza Last_Member_Query_Count volte ognuna a distanza Last_Member_Query_Interval. Se per un tempo pari al prodotto tra questi due valori, detto Last_Member_Query_Time, il router non riceve risposta può procedere a eliminare gruppi o sorgenti.

## Elezione Designated Router IGMP

Ogni LAN elegge un solo router che ha il compito di inviare periodicamente messaggi di Query agli host e di tracciare il loro stato di membership. Questo router è detto Designated Router o più propriamente Querier. Il meccanismo di elezione è molto semplice: ogni router mantiene un Other_Querier_Present timer che è aggiornato ogni volta che riceve una query da un router con indirizzo IP più basso del suo. Il Querier è il router con indirizzo IP più basso; se un altro router riceve una query da esso smette di inviare le proprie. Se un router che precedentemente era Querier non vede più arrivare Query, riprende lui a inviarle subentrando come nuovo Querier. Il fatto che in una LAN i messaggi vengano ricevuti da tutti i router ad essa connessi fa sì che ognuno possa costruirsi progressivamente lo stato di membership completo, così che se il Querier attuale dovesse cadere il nuovo Querier dispone già delle informazioni di stato aggiornate.