COS461: Computer Networks

Assignment #3 Frequently Asked Questions (FAQ)

Q1. There seems to be lots of stuffs, where should I start?
Q2. Why is the reference server closing the connection from my client after I send the SYN packet?
Q3. What am I allowed to modify in transport.c? What should I leave alone?
Q4. The specification says that I have to handle case X in the receiver, but my transmitter will never do that. Do I have to handle it?
Q5. I'm confused about how connection termination works.
Q6. Do I have to consider the case where a packet is truncated by the network? (i.e. the data length implied by the STCP header is less than the actual size of the sent packet)
Q7. Why this weird threaded model? It makes everything harder to debug. Why not just have the application directly call the transport layer?
Q8. What is the meaning of 'absolute time' in stcp_wait_for_event()?
Q9. What functions and data types can I use from the stub code in my solution?
Q10. Do I need to deal with the case that sequence number wraps around (goes over 2^32 and starts from 0 again)?
Q11. What is the meaning of __attribute__ ((packed))?
Q12. Do I have to set the source and destination ports in the TCP header?
Q13. Do I have to check for packet corruption with a checksum?
Q14. How can I accurately measure elapsed time?
Q15. The receive window has closed so I can't send any more data until I get an ACK. What should I do with the extra data that I can't send?
Q16. If I receive a segment with a sequence number less than the current ACK sequence number, can I just discard it?
Q17. Why am I getting network_io_socket.c:110: uint32_t _network_get_interface_ip(uint32_t): Assertion 'h == &result' failed.?


Q1. There seems to be lots of stuffs, where should I start?

A1. Read the TCP chapters in textbook, and RFC 793. Make sure to clearly understand how TCP works before you start. Then study the code and try to understand how the files (especially those realted to mysock and transport layer) are structured and connected with each other. Note that the only file you need to modify is transport.c, and that stcp_api.h contains all the functions you may use.

Q2. Why is the reference server closing the connection from my client after I send the SYN packet?

A2. Because it expects to find the ACK field set to 0 (even though the ACK flag is not set on the first SYN packet). It is a quirk of the reference solution.

Q3. What am I allowed to modify in transport.c? What should I leave alone?

A3. You can change anything you like in transport.c, except for code inside "#ifdef FIXED_INITNUM." (Grading depends on this staying the same!) You can add any other functions or data types that you wish.

Q4. The specification says that I have to handle case X in the receiver, but my transmitter will never do that. Do I have to handle it?

A4. Yes. There is nothing stopping us from testing your receiver against another student's transmitter, or against our own transport layer which specifically does X as a test case for your code.

Q5. I'm confused about how connection termination works.

A5. When the application requests that a mysocket is closed (via myclose()), your transport layer will receive a 'close requested event' from stcp_wait_for_event(); this is your cue to send a FIN segment once all pending data has been successfully transmitted. When you receive a FIN from the peer, and all expected data from the peer has been passed up to the application, you indicate that subsequent myread()s should return zero by calling stcp_fin_received().

Q6. Do I have to consider the case where a packet is truncated? (i.e. the data length implied by the STCP header is less than the actual size of the sent packet)

A6. No. You can assume that the implied payload length: len_from_stcp_network_recv - stcp_data_offset is correct and that no bytes at the tail end of the packet were lost, i.e. datagram transmission is all or nothing. If your buffer can fit it, you always get the whole datagram from the network layer as transmitted by the sender.

Q7. Why this weird threaded model? It makes everything harder to debug. Why not just have the application directly call the transport layer?

A7. Several reasons. For one, it actually makes things easier in the long run. If there was just one process/thread, how would the transport layer get control of the CPU when a timeout occurs or when a packet comes in? The only way to do this would be with signals. The signal model can work, but is much harder to debug with regards to things like race conditions. You have to explicitly deal with reentrancy issues and critical sections.

The event-driven model we have allows the transport layer to sleep until an interesting event happens. In some respects, this is a simpler model than you'd face in implementing a real TCP stack.

The second reason is that it abstracts the socket layer away from the transport layer. The layer you are writing is much more like a protocol stack that would actually fit into the operating system: you have a defined interface above you and below you, and you don't really need to know or care what the user processes above you are doing.

Q8. What is the meaning of 'absolute time' in stcp_wait_for_event()?

A8. It is the system time at which the function should return, if there is no pending event of interest. It is not a time interval relative to the current time, i.e. it has the same origin as functions like gettimeofday(2). Note that timespec used by stcp_wait_for_event() has a tv_nsec (nanosecond) field as opposed to the more common timeval which has a tv_usec (microsecond) field. If you use gettimeofday(2) to obtain the current time you will need to convert between the two struct types

Q9. What functions and data types can I use from the stub code in my solution?

A9. Anything declared in stcp_api.h or transport.h is fair game. You should not use any other methods or data types defined by the mysock implementation. You should study stcp_api.h in detail as these will be the primary (re: only) network/application I/O functions that transport.c will use. For example, you must use stcp_network_send() and stcp_network_recv() to send and receive packets from the network.

Q10. Do I need to deal with sequence number wrap around (goes over 2^32 and starts from 0 again)?

A10. No. This does add some complexity into the assignment. You're not required to deal with it. We're not going to test your programs to transfer 4 gigabytes of data :-) But keep in mind this happens in real TCP.

Q11. What is the meaning of __attribute__ ((packed))?

A11. In modern computer architectures, the internal representation of a struct with a bunch of fields might contain some bytes of inner padding to align the fields with the word boundaries (this is done for performance reasons). However when you try to send this data, you do not want to send unnecessary padding, because the receiving machine might have a different internal representation.

So, what you want the compiler to do is to eliminate any padding, and to pack all fields back to back, so that the internal and the network representation are the same (except perhaps for byte ordering). This is the role of the PACK directives.

Q12. Do I have to set the source and destination ports in the TCP header?

A12. Nope. Although this would be handled by 'real' TCP, because of the way we simulate the underlying unreliable network layer, the specifics of how ports are assigned depends on the underlying network layer in the mysock implementation. Consequently, the mysock layer takes care of assigning ports and setting these values accordingly. You do not have to handle demultiplexing of connections.

Q13. Do I have to check for packet corruption with a checksum?

A13. No, but you will probably still want to do other error checking in the header.

Q14. How can I accurately measure elapsed time?

A14. You can use the function gettimeofday(2). You cannot use any function from the real-time library (-lrt).

Q15. The receiver window has closed so I can't send any more data until I get an ACK. What should I do with the extra data that I can't send?

A15. You should only read as much data from the application as you're planning on sending. Let the rest of it sit there until you're ready to send it (i.e. an ACK opens up the receive window again).

Note that the transmitter has to keep track of the sender window, based on the 3072-byte receiver window, the current ACK sequence number and the outstanding amount of un-acknowledged data, in order to know how much to send.

Q16. If I receive a segment with a sequence number less than the current ACK sequence number, can I just discard it?

A16. No. You have to look at both the start and end of the segment. For example, if the ACK sequence number is 1000 (1000 is the next byte you expect), and a segment comes in with a sequence number of 800 and a length of 300 (i.e. ends at 1099), then you have to keep the data from 1000 to 1099. A similar case exists at the end of the receive window.

Q17. Why am I getting network_io_socket.c:110: uint32_t _network_get_interface_ip(uint32_t): Assertion 'h == &result' failed.?

A17. Assuming you are using the virtual machine, it is because you need to add "labpc-virtual.cs.princeton.edu" to the end of the first line of the hosts file (/etc/hosts)


Back to Assignments 3 page