INF3190 Obligatorisk oppgave: Linklagets flytkontroll

Formelt:

Denne obligatoriske oppgaven skal løses individuelt.
Innleveringen må være godkjent før innlevering av hjemmeeksamen 1.
For å bestå må innleveringen oppfylle kravene som er dokumentert i avsnittet "Oppgave" og du må kunne forklare løsningen din.

Oppgave

I denne oppgaven skal du skrive den første delen av et Linklag, flytkontrollen. Linklaget vil senere utvides med annen viktig funksjonalitet.

Dere vil fordype kunnskapen deres om programmering med UNIX-sockets. Det som trengs for å kunne løse oppgaven er "Berkeley UNIX System Calls and Interprocess Communication", beskrivelsen av glidende vinduer fra kapittel 3 i Tanenbaum, samt man-sidene på Linux-maskinene. Oppgaven skal programmeres i C.

Programmet dere skal skrive skal starte på to forskjellige maskiner i IFI sitt nettverk. Programmet skal ta et portnummer som kommandolinjeparameter. Mens programmet kjører tar det imot kommandoer fra tastaturet. Kommandoene skal brukes til oppkobling mot en annen maskin, for å overføre en fil til en oppkoblet maskin, og for å avslutte programmet.

Oppkoblingen skjer ved å opprette en "fysisk link" mellom to maskiner med hjelp av UDP-kommunikasjon. Programmet som initierer opprettelsen av forbindelsen kaller vi i det følgende klient, programmet som svarer på opprettelsen kaller vi tjener.

Init-fase / Opprettelse av en "fysisk link"

Opprettelse av den "fysiske linken" skal skje som følger:

Så snart et program anser den "fysiske linken" som up kan den begynne å sende rammer over den "fysiske linken".
(Tips: Det vil være lurt å skrive oppkoblingsmekanismen slik at flere "fysiske linker" mellom flere maskiner kan opprettes. Dette er ikke et krav for å få obligen godkjent. En av hjemmeeksamenene vil kreve en slik utvidelse. Det kan også være lurt å tenke på hvordan man setter opp rammestrukturen)

Flytkontrollen

Oppgaven krever en implementasjon av en flytkontrollmekanisme. Flytkontrollmekanismen skal være en glidende vindu mekanisme (sliding window). I denne oppgaven er stop-and-wait en lovlig løsning, men med hensyn til neste oppgavene anbefaler vi å implementere Go-Back-N eller Selective Repeat med opp til 10 utestående rammer (i hver retning).

Linklaget skal tilby pålitelig full duplex kommunikasjonstjeneste til høyere lag på følgende måte:

Flere detaljer om funksjonene finnes i avsnitt Spesifikke krav til implementasjonen.

Utlevering

Utdelt kode inneholder rammeverket dere skal bygge videre på. slow_receiver skal brukes for å skrive til fil. Den er laget slik at forsinkelser oppstår, slik at flytkontrollen slår til. delayed_sendto skal brukes for å sende data fra en maskin til en annet, som erstatning for write, send eller sendto. Den forsinker utsendingen - også dette vil føre til at flytkontrollen slår til. irq inneholder systemfunksjonen select. Vi anbefaler sterkt bruk av select framfor bruk av flere tråder eller prosesser i oppgavene i INF3190.

Utdelt kode har mange filer. Dere kan endre på alle filene om dere ønsker det, men vi har uthevet de filene hvor funksjonaliteten til denne oppgaven ligger:

Bakgrunnsinformasjon

Dere skal implementere en linklagsprotokoll på toppen av en transportlagsprotokoll. Hvis dere synes at dette ikke er korrekt fordi lagdelingen blir ødelagt, så vil vi i det følgende gi noen eksempler på systemer som er utbredt i den virkelige verden, men som bryter strukturen på samme måten. For eksempel er ATM i dag som oftest brukt som linklagsprotokoll under IP, som er en protokoll på nettverkslaget. Men det er da ATMs transportlag som ligger under IP. Et annet eksempel finnes på IFI: Wireless LAN brukere må installere en PPTP klient for å få lov til å bruke nettet fra maskinen sin. PPTP er en protokoll som bruker nettverkslagets IP, men selv tilbyr linklagstjenester etter at klienten har autentifisert seg.
Det samme gjør vi her: vi bruker UDP som om den ikke tilbyr flere tjenester enn et fysisk lag som knytter to nabomaskiner direkte sammen.

Spesifikke krav til implementasjonen

Koden deres skal kompilere og vil bli testet på IFIs login-maskiner (login.ifi.uio.no).

Opprettelse av den emulerte "fysiske linken"

Først skal dere lage funksjoner som gjør det mulig at naboer på deres linklag kjenner hverandre. Noder som snakker direkte med hverandre er naboer på det underliggende laget. I vårt tilfelle kan det være to vilkårlige maskiner på Internett, siden alle IP-adresserbare maskiner er naboer på transportlaget.

Funksjonene l1_connect og l1_linkup skal til sammen utgjøre de tjenestene som trengs for at linklaget kjenner en aktiv, bi-direksjonal "fysisk link" mellom to maskiner. Det å opprette en "fysisk link" er en asymmetrisk aktivitet mellom to programmer, som da tar rollene som klient og tjener.

Det fysiske laget

l1_connect

int l1_connect( const char* hostname, int port );

l1_connect kalles for å begynne opprettelsen av en "fysisk link" mellom den lokale maskinen og en annen maskin. Funksjonen returnerer etter å ha sendt "CONNECT"-pakken uten å vente på suksessrik oppkobling.

For å slå opp struct in_addr som tilhører et hostnavn vil man som oftest bruke systemfunksjonen gethostbyname. Siden programmet bruker UDP-kommunikasjon, trenger man ikke å opprette en ny socket for hver forbindelse. I stedet kan man bruke den delte socketen, og benytte sendto/recvfrom.
Returverdien til l1_connect er enten 0 eller en melding om en feil i sendeoperasjonen.

l1_linkup

static void l1_linkup( phys_conn_t *conn, const char* other_hostname, int other_port, int other_mac_address );

l1_linkup er en melding fra det fysiske laget til linklaget om at en "fysisk link" til en nabomaskin er opprettet.

Etter l1_linkup kan linklaget bruke linknummeret for å sende til naboen.

l1_linkup kalles etter mottak av en "CONNECT"-pakke, eller når det mottas svar på en "CONNECT"-pakke.

I tilfellet hvor det ble mottatt svar på en "CONNECT"-pakke vil det allerede være initialisert en phys_conn_t, og en sender da med en peker til denne. Det er gitt en funksjon get_phys_conn som kan brukes til å slå opp en allerede initialisert phys_conn_t.

Dersom l1_linkup kalles etter mottak av "CONNECT" kan en sende med NULL til conn-parameteret, og det er da l1_linkup sitt ansvar å initialisere en ny phys_conn_t struct. Dette kan gjøres ved kall på create_phys_conn. En benytter seg da av other_hostname og other_port, som er henholdsvis hostnavn og port for den aktuelle naboen som forbindelsen opprettes mot. Hostnavnet kan hentes fra en struct in_addr ved hjelp av gethostbyaddr(). Parameteret other_mac_address er naboens unike MAC-adresse, slik som spesifisert på kommandolinjen.

l1_send

int l1_send( int device, const char* buf, int length )

l1_send kalles av linklagsfunksjoner for å sende en ramme. Parameteret device identifiserer hvilken "fysisk link" det er som meldingen skal sendes på. buf peker til et buffer der den meldingen som sendes ligger. length inneholder det antallet tegn som blir sendt. l1_send bruker parameteren device for å initialisere alle parametere som sendeoperasjonen krever. Så bruker l1_send funksjonen delayed_sendto for å sende dataene på den "fysiske linken".

l1_handle_event

void l1_handle_event( );

l1_handle_event kalles av interrupt-handleren handle_event hvis nettverksaktivitet har oppstått. Dette er nesten garantert å bety at data har ankommet på en "fysisk link", dvs. at data må leses (helst med systemfunksjonen recvfrom) fra UDP socketen. Så er det nødvendig å forstå hvilken "fysisk link" dataene har kommet fra, og enten kalle l1_linkup eller sende de videre til l2_recv.

Linklaget

Rammer skal ikke være lengre enn 100 bytes. Dette gjelder både rammer som inneholder data og rammer som inneholder acknowledgements. Det er anbefalt å lage flere hjelpefunksjoner for håndtering av flytkontrollen, sending og mottak av rammer, og hvis dere bruker det, for timeout-håndtering.

Hver enkelt fysisk link har sin unike MAC-adresse i hver ende - tilsvarende nettverkskort. Hvis man vil støtte flere samtidige linker, må den lokale adressen initialiseres på forhånd med l2_init() for hver link.

Linklaget deres skal benytte recvfrom og delayed_sendto. recvfrom er en standard UNIX-funksjon, delayed_sendto følger med den utleverte koden og fungerer som UNIX-funksjonen sendto.

l2_send

int l2_send( int dest_mac_addr, const char* buf, int length )

l2_send kalles av nettverkslagsfunksjoner for å sende en pakke. Parameteret mac_address identifiserer hvilken annen maskin det er som meldingen skal sendes til;. buf peker til et buffer der den meldingen som sendes ligger. length inneholder det antallet tegn som blir sendt. For hvert kall lager l2_send en ramme med opp til 100 bytes lengde. l2_send bruker ikke flere enn en ramme for å sende buf. Hvis lengden er for stor sendes bare de første 100 bytes (minus lengden til rammeheaderen). Hvis l2_send har en åpning i det glidende vinduet for sending, vil den lagre rammen i vinduet og returnere 1. Hvis l2_send ikke har noen åpning vil den returnere 0.

l2_recv

void l2_recv( int device, const char* buf, int length )

Alle rammer som linklaget mottar over nettet skal leveres til høyerelagsprotokoller uten linklagsheadere, ved å kalle l3_recv. Hvis l3_recv returnerer 1 kan linklaget anta at dataene har blitt levert korrekt. Hvis l3_recv returnerer 0 har det oppstått en feil, og programmet skal forsøke å levere dataene ved en senere anledning.

Alle data skal leveres til høyrelagsfunksjonen l3_recv.

Programmet

Programmet benytter de funksjonene dere har laget over.

Innlevering

Dere skal levere følgende:

  1. Et designdokument som inneholder:
    • En diskusjon vedrørende måtene å håndtere flytkontroll på, og hvilke fordeler de mer avanserte glidende-vindue-protokollene har over enklere protokoller som f.eks. stop-and-wait.
    • Hvordan programmet er designet (gjerne en tegning som viser i hvilken rekkefølge de forskjellige funksjonene blir kalt).
    • Protokollen deres (rammeinndeling, headerinformasjon, glidende vindu).
    • Dokumentasjon om hvordan programmet skal startes evt. avsluttes.
    • Hvilke filer programmet består av (C filer, headerfiler osv.).
  2. Programkoden, hvor koden er godt kommentert. Dokumentér alle variabler og definisjoner. For hver funksjon i programmet skal følgende dokumenteres:
    • Hva funksjonen gjør.
    • Hva inn- og ut-parametre betyr og brukes til.
    • Hvilke globale variable funksjonen endrer.
    • Hva funksjonen returnerer.
    • Andre særegenheter som er viktig å vite om (f.eks. feilsituasjoner).

Krav til innleveringen

Designdokumentet skal skrives vha. et egnet verktøy, f.eks. LaTeX, Word, etc. Dokumentet skal inneholde besvarelsen og de etterspurte figurer, samt ha en forside hvor følgende opplysninger er angitt: Navn - brukernavn - dato - kurs
Før levering skal dokumentet konverteres til pdf format. Hverken et Word/Works/OpenOffice/TeX -dokument eller en vanlig editorfil (plain text) godtas.

Koden må være kompilerbare tekstfiler.

Omfanget av dokumentet trenger ikke nødvendigvis være så stort, men må inneholde tilstrekkelig informasjon til å oppfylle kravet som beskrevet under 'oppgave'. Det som er viktig er å dokumentere forståelse for de berørte emner, i tillegg til selve gjennomføringen.

Elektronisk innlevering: Alt skal leveres elektronisk hvor alle filer (Makefile, *.c, *.h, README.pdf, etc.) er samlet i en katalog med deres UIO-brukernavn som navn. Av denne katalogen lager dere en komprimert tar-ball -- bruk kommandoen tar zcvf username.tgz username. Link for den elektroniske innleveringen kommer på INF3190 sine hjemmesider.

Innleveringsfrist: Fredag 26. februar 2010 klokken 18:00

Husk at du ikke kan levere kopi av andres besvarelser, men skal levere en egenprodusert løsning. Les kravene til innleveringer på www.ifi.uio.no/studier/studentinfo.html#krav.

Forklaringskrav

Faglærere vil gjennomføre stikkprøver blant de innleveringer som oppfyller kravene for godkjenning. Det innkalles til uformelt møte. Forklaringen omfatter linklaget generelt, linklagsteknikker brukt oppgaven, innlevert kode og programflyt. Hvis forklaringen ikke er tilstrekkelig underkjennes innleveringen. Hvis innleveringen underkjennes pga stikkprøven kan man velge formell muntlig prøve med faglæreren som omfatter det samme materialet og som gjelder godkjenning av obligen.