The socket System Call

The socket( ) system call creates a new endpoint for a communication between two or more processes. In our example program, it is invoked in this way:

sockfd = socket(PF_INET, SOCK_DGRAM, 0);

The socket( ) system call returns a file descriptor. In fact, a socket is similar to an opened file because it is possible to read and write data on it by means of the usual read( ) and write( ) system calls.

The first parameter of the socket( ) system call represents the network architecture that will be used for the communication, as well as a particular network layer protocol adopted by the network architecture. The pf_inet macro denotes both the IPS architecture and Version 4 of the IP protocol (IPv4). Linux supports several different network architectures; a few of them are shown in Table 181 earlier in this chapter.

The second parameter of the socket( ) system call specifies the basic model of communication inside the network architecture. As we already know, the IPS architecture offers essentially two alternative models of communication:

Reliable, connection-oriented, stream-based communication implemented by the TCP transport protocol

SOCK_DGRAM

Unreliable, connection-less, datagram-based communication implemented by the UDP transport protocol

Moreover, the special sock_raw value creates a socket that can be used to directly access the network layer protocol (in our case, the IPv4 protocol).

In general, a network architecture might offer other models of communication. For instance, sock_seqpacket specifies a reliable, connection-oriented, datagram-based communication, while sock_rdm specifies a reliable, connection-less, datagram-based communication; however, neither of them is available in the IPS.

The third parameter of the socket( ) system call specifies the transport protocol to be used in the communication; in general, for any model of communication, the network architecture might offer several different protocols. Passing the value 0 selects the default protocol for the specified communication model. Of course, when using the IPS, the value 0 selects the TCP transport protocol (ipproto_tcp) for the sock_stream model and the UDP protocol (ipproto_ip) for the sock_dgram model. On the other hand, the sock_raw model allows the programmer to specify any one of the network-layer service protocols of the IPS — for instance, the Internet Control Message Protocol (ipproto_icmp), the Exterior Gateway Protocol (ipproto_egp), or the Internet Group Management Protocol (ipproto_igmp).

The socket( ) system call is implemented by means of the sys_socket( ) service routine, which essentially performs three actions:

1. Allocates a descriptor for the new BSD socket (see the later section Section 18.1.3).

2. Initializes the new descriptor according to the specified network architecture, communication model, and protocol.

3. Allocates the first available file descriptor of the process and associates a new file object with that file descriptor and with the socket object.

18.2.1.1 Socket initialization

Let's return to the service routine of the socket( ) system call. After having allocated a new BSD socket, the function must initialize it according to the given network architecture, communication model, and protocol.

For every known network architecture, the kernel stores a pointer to an object of type net_proto_family in the net_families array. Essentially, the object just defines the create method, which is invoked whenever the kernel initializes a new socket of that network architecture.

The create method corresponding to the pf_inet architecture is implemented by inet_create( ) . This function checks whether the communication model and the protocol specified as parameters of the socket( ) system call are compatible with the IPS network architecture; then it allocates and initializes a new INET socket and links it to the parent BSD socket.

18.2.1.2 Socket's files

Before terminating, the socket( )'s service routine allocates a new file object and a new dentry object for the sockfs's file of the socket; then it associates these objects with the process that raised the system call through a new file descriptor (see Section 12.2.6).

As far as the VFS is concerned, any file associated with a socket is in no way special. The corresponding dentry object and inode object are included in the dentry cache and in the inode cache, respectively. The process that created the socket can access the file by means of the system calls that act on already opened files — that is, the system calls that receive a file descriptor as a parameter. Of course, the file object methods are implemented by functions that operate on the socket rather than on the file.

As far as the User Mode process is concerned, however, the socket's file is somewhat peculiar. In fact, a process can never issue an open( ) system call on such a file because it never appears on the system directory tree (remember that the sockfs special filesystem has no visible mount point). For the same reason, it is not possible to remove a socket file through the unlink( ) system call: the inodes belonging to the sockfs filesystem are automatically destroyed by the kernel whenever the socket is closed (released).

Continue reading here: The bind System Call

Was this article helpful?

0 0