Introduction To Linux: Kernel Network Interface
Introduction To Linux: Kernel Network Interface
Introduction To Linux: Kernel Network Interface
Introduction to Linux
·
Linux is developed world wide. It is an open development project, meaning everyone
who wants to can become involved. Because it is worldwide, a fast and easy form of
communication is needed so different people and groups can keep updated with what is
going on with Linux.
For a normal network programmer, the front end to the networking services of the Linux
kernel are available through the following C library routines :
socket()
bind()
listen()
connect()
accept()
sendto()
recvfrom()
send()
recv()
The socket() function is used to create a new socket. All the operations with the
various different protocols occur with a socket. As the routine socket() returns a file
descriptor, the usual file operations can apply to it, i.e. read(), write(), etc.
The bind() function is used to tie a newly created socket to a port. The port along
with the IP address of the network interface is used to uniquely identify a socket. When
a socket is bound to a port, any packet that arrives with the port in its destination field is
passed on to that socket controller.
The listen() function is used for server side programming. After a socket is created
and bound to a port, calling the listen() function sets the socket to the listen state. This
means that the socket is willing to accept connections from foreign hosts.
When the server side calls the accept() function, the program blocks and continually
polls the socket until it receives a connection request from another host. Only when the
connection is established is the server program woken up and allowed to process a request
from the foreign host.
socket: This structure is the basis for the implementation of the BSD socket interface.
The system call socket() sets up and initialises the structure.
sk_buff: This structure manages the individual communications packets arriving and be
ing sent from the host. It buffers the input and output. The structure holds the
packets before either sending them onto the network interface for transmission, or
sending them onto the higher layers for processing and eventually arriving at the
application layer.
INET: This structure administers the networkspecific parts of the sockets. It is required
for TCP, UDP and RAW sockets.
proto: This structure contains a number of operations that are the same for all protocols.
It means that the actions only need to be programmed once and avoids implemen
tation errors.
sockaddr(sockaddr_in): These are necessary to support the different address formats for
different address families.
tcp_connect()
inet_connect()
sys_connect()
sys_socketcall()
connect()
User Space
Kernel Space
On the user side, a program executes a system socket command, such as socket(),
bind() or connect(). This is passed into the kernel side through the sys_socketcall() func
tion located in the /usr/src/linux/net/socket.c file.
Design and Implementation
Design Approach
We started of to create simple Server/Client which would support simple User level functionality
of converting characters from lower case to upper case. We wanted to keep it very simple and
make it usable for other user level services too. So we decided to implement it in form of API like
functions.
Major part of designing task was to implement most reliable TCP state machine.
TCP Header
Below is the standard TCP header we are using for our client/server
struct {
unsigned short srcPort;
unsigned short dstPort;
unsigned int seqNo;
unsigned int ackNo;
unsigned short dataOffset;
unsigned short reserved;
char URG;
char ACK;
char PSH;
char RST;
char SYN;
char FIN;
unsigned short windows;
unsigned short chkSum;
unsigned short urgPtr;
unsigned char option[40];
}ztcp;
struct {
char data [SIZE];
}zdata;
struct {
ztcp header;
zdata data;
}zpacket;
long SEG_SEQ;
long SEG_ACK;
long SEG_LEN;
long SEG_WND;
FILE *file;
}
Connection Eshtablishment
Data Transfer
Conceptually, each byte sent is assigned a sequence number and the receiver then sends an
acknowledgement back to the sender that effectively states that they received it. What is done in
practice is only the first data byte is assigned a sequence number which is inserted in the
sequence number field and the receiver sends an acknowledgement value of the next byte they
expect to receive. Data is sent along with each octet and server converts them into upper case
send them back to requesting client.
·
Fig. Data Transfer Client Side
Connection termination
The connection termination phase uses, at most, a four-way handshake, with each side of the
connection terminating independently. When an endpoint wishes to stop its half of the
connection, it transmits a FIN packet, which the other end acknowledges with an ACK. Therefore,
a typical teardown requires a pair of FIN and ACK segments from each TCP endpoint.
A connection can be "half-open", in which case one side has terminated its end, but the other has
not. The side that has terminated can no longer send any data into the connection, but the other
side can.
It is also possible to terminate the connection by a 3-way handshake, when host A sends a FIN
and host B replies with a FIN & ACK (merely combines 2 steps into one) and host A replies with
an ACK. This is perhaps the most common method.
Finally, it is possible for both hosts to send FINs simultaneously then both just have to ACK. This
could possibly be considered a 2-way handshake since the FIN/ACK sequence is done in parallel
for both direction
Ours is a Iterative server which creates arrays of TCBs. We have limited our array to 10 at
present. After Connection establishment whenever a packet comes in it checks for its source ip
address and port number and checks TCB array for any present connection with that node. If it
finds that packet is coming from some new node then it create new entry in TCB array structure
and initiates state machine.
When Server is initiated it binds to socket and goes into to Listen State. When connection is
already present for incoming packet the state processing machine handles processing for the
current state as well as decides the next state for the connection,
Suppose TCB array is full and there is no place for new connection then server would send RST
to the requesting client.
Architecture
Figure Architecture
Return:
-壱If the packet is available, it returns ‘0’
-弐If no packet is received from anywhere, it returns -1.
Return:
-壱Returns ‘0’ if there no error.
-弐Returns ‘-1’ if there is any error.
int zRetransmit()
Description:
-壱This function goes through all the TCBs and looks for un-acknowledged data.
-弐If there is any un-acknowledged data, it looks at the retransmit time for this data.
-参If the current time is < retransmit time, skip, and go to next TCB
-四If the current time is >= retransmit rime, retransmit the packet. And reset the retransmit time
by next interval.
-伍Go to the next TCB.
Return:
-壱Return ‘0’ if there is no error.
-弐Return ‘-1’ if there is any error.
getTCB (zpacket *recvPkt, zpacket *sendPkt, int sockfd)
Description:
-壱First get the sender address and port number from the recvPkt
-弐Lookup the TCB matching these address and port number.
-参If TCB is not found, and the recvPkt is SYN request packet, then create a new TCB for this
connection.
-四Based on the current state of the TCB and control bits in the packet, call the TCP state
machine.
-伍The TCP state machine will decide the next state of the TCB and the next action to take. For
example if the packet is SYN request then the next state would be SYN-RCVD and next action
would be send SYN-ACK.
-六Call the function copyClientData() that copies the data from the recvPkt to the sendPkt and
converts it into the upper case.
-七Prepare the packet to be sent in the sendPkt with the control bits and proper seq-num and
ack-num.
Return:
-壱Returns the value corresponding to the action to be taken.
int zserverSocket()
Description:
-壱create a struct zionSocket
-弐call the socket() function to create a UDP socket and keep this socket fd in the zionSocket
-参Return the address of the zionSocket.
·Project Postmorten
Problems faced:
1. How to wait for packet on the socket.
Solution: Found the select call provides the facility to wait
for incoming data on socket fd.
·
·Conclusion
To Conclude I’ll summarize some of the achievement and some of the shortfalls of our
adventure. We started of to implement TCP, and what I think we ended up is a protocol which is
not totally reliable in the sense it doest not support flow control fully i.e out of sequence packets
are not put back in order. Our server/client is able to connect successfully to others server/client,
although we faced lot of issues with network byte order used by other teams. Basic connection
establishment and connection termination is successfully performed. There are also checks
involving incorrect states of connection and following TCP state diagram.
Other than just the technical difficulties we faced we were having problems managing all our code
files. So we think central repositories managing code are good for handling such large projects.