Analysis of the implementation of sockets in Linux-------creation

Source: Internet
Author: User
Tags goto

A socket is a method of communicating with a system process using the file descriptor of the systems.

1. The following is the structure that describes the socket address:

struct SOCKADDR {

sa_family_t sa_family; /* Address family, AF_XXX */

If the TCP/IP protocol is used, the Af_inet

Char sa_data[14]; /* bytes of protocol address */

};

2, the socket system calls:

We create sockets that are created with sockets.

System calls to the socket:

Each network operation function has a corresponding macro definition code

#define SYS_SOCKET 1/* Sys_socket (2) */

#define SYS_BIND 2/* Sys_bind (2) */

#define SYS_CONNECT 3/* Sys_connect (2) */

#define SYS_LISTEN 4/* Sys_listen (2) */

#define SYS_ACCEPT 5/* SYS_ACCEPT (2) */

#define SYS_GETSOCKNAME 6/* SYS_GETSOCKNAME (2) */

#define SYS_GETPEERNAME 7/* SYS_GETPEERNAME (2) */

#define SYS_SOCKETPAIR 8/* Sys_socketpair (2) */

#define SYS_SEND 9/* Sys_send (2) */

#define SYS_RECV/* SYS_RECV (2) */

#define SYS_SENDTO/* SYS_SENDTO (2) */

#define SYS_RECVFROM/* SYS_RECVFROM (2) */

#define SYS_SHUTDOWN/* Sys_shutdown (2) */

#define SYS_SETSOCKOPT/* SYS_SETSOCKOPT (2) */

#define SYS_GETSOCKOPT/* SYS_GETSOCKOPT (2) */

#define SYS_SENDMSG/* SYS_SENDMSG (2) */

#define SYS_RECVMSG */sys_recvmsg (2) */

In Linux, all network functions are implemented through Sys_socketcall:

Asmlinkage long Sys_socketcall (int call, unsigned long __user *args)

{

unsigned long a[6];

Unsigned long a0, A1;

int err;

Judgment of the scope of the incoming parameter

if (Call < 1 | | call > SYS_RECVMSG)

Return-einval;

/* Copy_from_user should be SMP safe. */

if (Copy_from_user (A, args, nargs[call))//Copy the user-state array to a

Return-efault;

Err = Audit_socketcall (Nargs[call]/sizeof (unsigned long), a);//record Audit data for Sys_socketcall

if (ERR)

return err;

a0 = a[0];

a1 = a[1];

Switch (call) {

Case Sys_socket:

Err = Sys_socket (a0, A1, A[2]);

Break

Case Sys_bind:

Err = Sys_bind (a0, (struct sockaddr __user *) a1, a[2]);

Break

Case Sys_connect:

Err = Sys_connect (a0, (struct sockaddr __user *) a1, a[2]);

Break

Case Sys_listen:

Err = Sys_listen (a0, A1);

Break

Case SYS_ACCEPT:

Err =

Sys_accept (a0, (struct sockaddr __user *) A1,

(int __user *) a[2]);

Break

Case Sys_getsockname:

Err =

Sys_getsockname (a0, (struct sockaddr __user *) A1,

(int __user *) a[2]);

Break

Case Sys_getpeername:

Err =

Sys_getpeername (a0, (struct sockaddr __user *) A1,

(int __user *) a[2]);

Break

Case Sys_socketpair:

Err = Sys_socketpair (a0, A1, A[2], (int __user *) a[3]);

Break

Case Sys_send:

Err = Sys_send (a0, (void __user *) a1, A[2], a[3]);

Break

Case SYS_SENDTO:

Err = Sys_sendto (a0, (void __user *) a1, A[2], a[3],

(struct sockaddr __user *) a[4], a[5]);

Break

Case SYS_RECV:

Err = Sys_recv (a0, (void __user *) a1, A[2], a[3]);

Break

Case Sys_recvfrom:

Err = Sys_recvfrom (a0, (void __user *) a1, A[2], a[3],

(struct sockaddr __user *) a[4],

(int __user *) a[5]);

Break

Case Sys_shutdown:

Err = Sys_shutdown (a0, A1);

Break

Case SYS_SETSOCKOPT:

Err = sys_setsockopt (a0, A1, A[2], (char __user *) a[3], a[4]);

Break

Case SYS_GETSOCKOPT:

Err =

Sys_getsockopt (A0, A1, A[2], (char __user *) a[3],

(int __user *) a[4]);

Break

Case SYS_SENDMSG:

Err = sys_sendmsg (a0, (struct MSGHDR __user *) a1, a[2]);

Break

Case SYS_RECVMSG:

Err = sys_recvmsg (a0, (struct MSGHDR __user *) a1, a[2]);

Break

Default

err =-einval;

Break

}

return err;

}

The Linux application Layer program implements network communication through the standard Bsdsocket interface. In BSD, the socket is used to describe a socket, mainly used in the BSD socket interface layer.

/**

* struct Socket-general BSD socket

* @state: Socket State (%ss_connected, etc)

* @flags: Socket flags (%SOCK_ASYNC_NOSPACE, etc)

* @ops: Protocol specific socket operations

* @fasync_list: Asynchronous Wake Up List

* @file: File back pointer for GC

* @sk: Internal networking protocol agnostic socket representation

* @wait: Wait queue for several uses

* @type: Socket type (%sock_stream, etc)

*/

struct Socket {

Socket_state State;

unsigned long flags;

const struct PROTO_OPS *ops;//socket function Operation table

struct Fasync_struct *fasync_list;

struct file *file;

struct sock *sk;

wait_queue_head_t wait;

Types of short type;//datagrams

};

struct sock *sk, pointing to the socket interface corresponding to the inet socket struct struct sock,

Create related sockets according to the Protocol

struct Net_proto_family {

int family;

Int (*create) (struct net *net, struct socket *sock, int protocol);//Creation function of the Protocol family

struct module *owner;

};

such as: IPV4

static struct net_proto_family Inet_family_ops = {

. Family = pf_inet,

. Create = Inet_create,

. Owner = This_module,

};

3. Creation of sockets:

Asmlinkage long Sys_socket (int family, int type, int protocol)

{

int retval;

struct socket *sock;

Creating sockets

retval = sock_create (family, type, protocol, &sock);

if (retval < 0)

Goto out;

retval = SOCK_MAP_FD (sock);//Associated File system

if (retval < 0)

Goto Out_release;

Out

/* It May is already another descriptor 8) not kernel problem. */

return retval;

Out_release:

Sock_release (sock);

return retval;

}

int sock_create (int family, int type, int protocol, struct socket **res)

{

Return __sock_create (Current->nsproxy->net_ns, family, type, protocol, res, 0);

}

The creation function of the socket

static int __sock_create (struct net *net, int family, int type, int protocol,

struct socket **res, int kern)

{

int err;

struct socket *sock;

const struct net_proto_family *pf;

/*

* Check protocol is in range

*/

if (Family < 0 | | family >= nproto)

Return-eafnosupport;

if (Type < 0 | | type >= SOCK_MAX)

Return-einval;

/* compatibility.

This uglymoron was moved from INET layer to here to avoid

Deadlock in module load.

*/

if (family = = Pf_inet && type = = Sock_packet) {

static int warned;

if (!warned) {

warned = 1;

PRINTK (kern_info "%s uses obsolete (pf_inet,sock_packet) \ n",

CURRENT->COMM);

}

Family = Pf_packet;//af_inet

}

Tracing this function will find

Err = security_socket_create (family, type, protocol, Kern);

if (ERR)

return err;

/*

* Allocate the socket and allow the family to set things up. If

* The protocol is 0, the family are instructed to select a appropriate

* Default.

*/

Sock = Sock_alloc ();//Assigning the socket structure body space

if (!sock) {

if (Net_ratelimit ())

PRINTK (kern_warning "Socket:no more sockets\n");

Return-enfile; /* Not exactly a match, but its the

Closest POSIX thing */

}

Sock->type = type;

#if defined (CONFIG_KMOD)

/* Attempt to load a protocol module if the find failed.

*

* 12/09/1996 marcin:but! This makes really only sense, if the user

* Requested real, full-featured networking support upon configuration.

* Otherwise Module Support would break!

*/

if (net_families[family] = = NULL)

Request_module ("net-pf-%d", family);

#endif

Rcu_read_lock ();

PF = rcu_dereference (net_families[family]);

err =-eafnosupport;

if (!PF)

Goto Out_release;

/*

* We'll call the->create function, which possibly is in a loadable

* module, so we had to bump that loadable module refcnt first.

*/

if (!try_module_get (Pf->owner))

Goto Out_release;

/* now protected by module ref count */

Rcu_read_unlock ();

Err = pf->create (NET, sock, protocol);

if (Err < 0)

Goto Out_module_put;

/*

* Now to bump the refcnt of the [loadable] module, the owns this

* Socket at sock_release time we decrement it refcnt.

*/

if (!try_module_get (Sock->ops->owner))

Goto Out_module_busy;

/*

* Now that we ' re do with the->create function, the [loadable]

* Module can has its refcnt decremented

*/

Module_put (Pf->owner);

Err = security_socket_post_create (sock, family, type, protocol, Kern);

if (ERR)

Goto Out_sock_release;

*res = sock;

return 0;

Out_module_busy:

err =-eafnosupport;

Out_module_put:

Sock->ops = NULL;

Module_put (Pf->owner);

Out_sock_release:

Sock_release (sock);

return err;

Out_release:

Rcu_read_unlock ();

Goto Out_sock_release;

}

Analysis of the implementation of sockets in Linux-------creation

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.