struct sock_common {

unsigned short skc_family; volatile unsigned char skc_state;

struct hlist_node skc_node;

unsigned int skc_hash;

atomic_t skc_refcnt;

struct proto *skc_prot;

struct sock i struct sock_common sk common;

struct sk_buff_head struct sk buff head sk_receive_queue; sk_write_queue;

struct timer_list void sk_timer;

(♦sk_data_ready)(struct sock

The sock structures of the system are organized in a protocol-specific hash table. skc_node is the hash linkage element, while skc_hash denotes the hash value.

Data are sent and received by placing them on wait queues (sk_receive_queue and sk_write_queue) that contain socket buffers.

In addition, a list of callback functions is associated with each sock structure used by the kernel to draw attention to special events or bring about state changes. Our simplified version shows only one function pointer called sk_data_ready because it is the most significant and its name has already been mentioned several times in the last few chapters. The function it contains is invoked when data arrive for handling by the user process. Typically, the value of the pointer is sock_def_readable.

There is a great danger of confusion between the ops element of type struct proto_ops in the socket structure and the prot entry of type struct proto in sock. The latter is defined as follows:

include/net/sock.h struct proto { void int int struct sock *

int int int void int int int int int int

(*close)(struct sock *sk, long timeout); (*connect)(struct sock *sk, struct sockaddr *uaddr, int addr_len); (*disconnect)(struct sock *sk, int flags);

(*ioctl)(struct sock *sk, int cmd, unsigned long arg); (*init)(struct sock *sk); (*destroy)(struct sock *sk); (*shutdown)(struct sock *sk, int how); (*setsockopt)(struct sock *sk, int level, int optname, char _user *optval, int optlen); (*getsockopt)(struct sock *sk, int level, int optname, char _user *optval, int _user *option);

(*sendmsg)(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, size_t len); (*recvmsg)(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, size_t len, int noblock, int flags, int *addr_len); (*sendpage)(struct sock *sk, struct page *page, int offset, size_t size, int flags); (*bind)(struct sock *sk, struct sockaddr *uaddr, int addr_len); struct sockaddr *uaddr, int addr_len);

Both structures have member elements with similar (and often identical) names although they represent different functions. Whereas the operations shown here are used for communication between the (kernelside) socket layer and transport layer, the functions held in the function pointer block of the socket structure are designed to communicate with system calls. In other words, they form the link between user-side and kernel-side sockets.

12.10.2 Sockets and Files

Userspace processes access sockets using normal file operations once a connection has been established. How is this implemented in the kernel? Owing to the open structure of the VFS layer (as discussed in Chapter 8), very few actions are needed.

VFS inodes of the virtual filesystem are discussed in Chapter 8. Each socket is assigned an inode of this type, which is, in turn, linked with the other structures associated with normal files. The functions for manipulating files are stored in a separate pointer table:

Continue reading here: Netsocketc

Was this article helpful?

0 0