FAQ - Oblig 1
Q: Jeg trenger hjelp, hva gjør jeg?
A: Først leser du dette. Deretter kan du sende en mail til orakel, samt møte opp på orakeltimer.
Q: Jeg sliter med å forstå hvor jeg skal begynne?
A: Det er mye å sette seg inn i fra første stund. Derimot trenger man ikke gape over alt på en gang. Det kan være lurt å begynne med det enkleste først, som å forstå hvordan man skal få satt opp en forbindelse mellom to maskiner. For å forstå dette, bør en ha en grunnleggende forståelse for prekoden. Deretter kan det være lurt å tenke på hvordan struktur man ønsker å benytte seg av for å håndtere flere forbindelser pr node i nettverket. Dette er en utvidelse som vil være påkrevd i senere oppgaver. Det er lagt ut et forslag til struktur i prekoden, denne kan dere benytte om dere ønsker.
Q: Hva er sliding window?
A: Sjekk læreboken (Tanenbaum). Det står masse nyttig om sliding windows i kapittel 3.4 fra side 211.
Q: Hvordan bruker jeg Berkeley Sockets?
A: Det står en meget bra artikkel på wikipedia, du kan også lese dokumentet referert i oppgaveteksten.
Q: Hva betyr - error: dereferencing pointer to incomplete type?
A: Det betyr somregel at du prøver og bruke en struct, men har glemt og definere den. Husk alltid å include de korrekte headerfilene.
Q: Hvor mange sliding windows trenger jeg?
A: Du trenger ett sliding window på hver side av en 1:1 connection, dvs. ett sliding window per unike linknummer.
Q: Kan jeg endre på prekoden?
A: For all del, prekoden er bare veiledende og du kan gjøre de endringer du føler er nødvendig. Det som er viktig er å holde seg til de funksjonskallene som er gitt i oppgaveteksten.
Q: Hvordan sammenligner jeg strukter?
A: Du må sammenligne hvert element i struktene, hver for seg.
Q: Hvordan sender jeg en struct over socketen?
A: En struct er egentlig bare en samling av byte på rekke og rad, derfor går det fint å caste om structen til en (char *) som peker på structen. Og du kan da caste om andre veien på motsatt side når du mottar den. Derimot kan structen behandles ulikt på ulike maskiner. Dette grunnet f.eks alignment, endianess etc. Siden vi i denne obligen bruker kun ifi sine maskiner så vil det fungere, men det er noe å tenke over.
Q: Hvordan får man MAC-adressen i l1_connect()?
A: Det er egentlig ikke meningen at det fysiskelaget skal vite om MAC-adressen, så denne bør du hente fra linklaget ditt. Dette kan gjøres ved f.eks å lage en l2_connect som kaller l1_connect for deg.
Q: Hvordan fungerer my_conns og mac_to_device datastrukturene?
A: my_conns er en struktur som skal inneholde informasjonen man trenger for hver forbindelse. Dette er initielt vertsnavn på motparten av forbindelsen og porten. Hvis en ønsker kan det være lurt å legge til flere ting i denne strukturen for å forenkle hver operasjon på en forbindelse. Etterhvert vil det være påkrevd å ha kunne flere forbindelser, og da kan denne strukturen være en god begynnelse for å lage flere interfaces på en node i nettet. my_conns er initialisert til å ha 0 på remote_hostname og -1 på port. Indekseringen i arrayen spiller forsåvidt ingen rolle, så lenge man har en fornuftig måte å slå opp forbindelsen man ønsker å bruke.
mac_to_device er en struktur som skal holde oversikt over hvilke mac-adresser som er tilgjengelig på de ulike forbindelsene, variabelen device som sendes med fra og til det fysiskelaget kan slåes opp via denne tabellen med en mac-adresse. Et eksempel flere har stusset på er i l2_linkup, hvor man bruker mac_to_device. Alle nodene blir satt opp til at indeksen local_mac blir satt til device 0, derimot må en fylle inn i tabellen når en får vite om nye mac-adresser som finnes på nettet (ved f.eks en CONNECT-UP sekvens), og det er her man benytter remote_mac feltet i datastrukturen.
Q: Jeg får ikke skrevet ut l3buf og l2buf i henholdsvis l4 og l3?
A: Dette er mest sannsynligvis grunnet det kan ligge en en '\0' byte i headeren på l3 eller l4. Det kan derfor være lurt for å sjekke at meldingene kommer riktig frem med å skrive ut på adressen som den faktiske meldingen ligger. F.eks l3buf + sizeof(struct l4Header)
Q: Hvilken adresse/port er det jeg skal bruke som destinasjonsadresse/port ved kall på l4_send()?
A: For å gjøre ting enkelt så er det gjort slik at host-adressen er den samme som mac-adressen. Så "dest_addr" til l4_send() er den samme som destinasjonens mac-adresse. Hvilken port en sender med nå har ikke noen betydning, siden alt sendes til samme "prosess" på lag 5 uansett. Det kan være hvilket som helst tall under 1024 (MAX_PORTS).
Q: Får en flere forsøk på å levere den obligatoriske oppgaven?
A: Ja, en får to forsøk på å få godkjent den obligatoriske oppgaven
Q: Hjelp, jeg rekker ikke bli ferdig innen tidsfristen på den obligatoriske oppgaven. Kan jeg få utsettelse?
A: Send en mail til haakonks (a) simula.no med en forklaring, så kan det muligens ordnes.
Q: Alt stopper opp i l5_handle_keyboard, hvorfor?
A: Prekoden tilbyr et rammeverk for å la hvert lag leve i samme prosess, og for å gi "avbrudd" når det kommer trafikk frå nettverket eller noe skjer på tastaturet. Problemet kan oppstå når for eksempel applikasjonslaget prøver å sende mye data inne i en while-løkke som kun avslutter når alt er sendt. Siden alt er i samme prosess kan hver del av koden blokkere. Det er derfor viktig å ikke ha løkker som ikke gir fra seg kontrollen tilbake til event-løkka i irq.c. Dette er viktig i alle lagene, ikke bare applikasjonslaget.
Q: sockaddr_in som jeg får fra recvfrom() fylles inn med gale verdier
A: Dette er som regel på grunn av at addrlen-feltet (siste parameter til recvfrom) ikke er initialisert riktig. addrlen må være en peker til en socklen_t, initialisert til størrelsen på en sockaddr_in.
eksempel:
socklen_t addrlen = sizeof(struct sockaddr_in); /* ... */ int len = recvfrom(my_udp_socket, buf, sizeof buf, 0, (struct sockaddr *) &fromaddr, &addrlen);