connect()
Table of Contents
The connect()
system call is a crucial function in Linux that enables processes to establish connections between sockets. By initiating a connection request to a remote host, connect()
plays a pivotal role in network communication, allowing programs to connect and exchange data over various types of connections, such as TCP/IP. Understanding the connect()
system call is essential for building networked applications and leveraging the power of networking in Linux environments.
#include <sys/socket.h>
int connect(int sockfd, const struct sockaddr *addr,
socklen_t addrlen);
Prerequiste definiton
The connect()
system call connects the socket referred to by the file descriptor sockfd
to the address specified by addr
.The addrlen
argument specifies the size of addr. The format of the address in addr is determined by the address space of the socket sockfd
; see socket(2) and address_families for further details.
The definition for connect can be founde here.
SYSCALL_DEFINE3(connect, int, fd, struct sockaddr __user *, uservaddr, int, addrlen)
{
return __sys_connect(fd, uservaddr, addrlen);
}
Let’s break down the code:
This code defines the connect
system call with three arguments: fd
, uservaddr
, and addrlen
.
Here’s what each argument represents:
int fd
: The file descriptor of the socket to connect.struct sockaddr __user *uservaddr
: A pointer to thesockaddr structure
that holds the address to which the socket should connect. The __user attribute is typically used in the kernel to denote a user-space memory pointer.int addrlen
: The length of thesockaddr
structure.
The SYSCALL_DEFINE3 macro expands to the actual definition of the system call, which includes the function body. In this case, the body simply calls the __sys_connect function and returns its result.
int __sys_connect(int fd, struct sockaddr __user *uservaddr, int addrlen)
{
int ret = -EBADF;
struct fd f;
f = fdget(fd);
if (f.file) {
struct sockaddr_storage address;
ret = move_addr_to_kernel(uservaddr, addrlen, &address);
if (!ret)
ret = __sys_connect_file(f.file, &address, addrlen, 0);
fdput(f);
}
return ret;
}
This function is responsible for connecting a socket to the specified address.
Implementation of the __sys_connect function
, which is called by the connect()
system call. This function is responsible for connecting a socket to the specified address.
Let’s break down the code:
int __sys_connect(int fd, struct sockaddr __user *uservaddr, int addrlen)
{
int ret = -EBADF;
struct fd f;
f = fdget(fd);
if (f.file) {
struct sockaddr_storage address;
ret = move_addr_to_kernel(uservaddr, addrlen, &address);
if (!ret)
ret = __sys_connect_file(f.file, &address, addrlen, 0);
fdput(f);
}
return ret;
}
Here’s an explanation of the code:
-
The function
__sys_connect
takes three arguments:fd (the file descriptor of the socket to connect)
,uservaddr (a pointer to the user-space sockaddr structure containing the address to connect to)
, andaddrlen (the length of the sockaddr structure)
. -
The variable
ret
is initialized with the value -EBADF, which stands for “bad file descriptor.” This is used as a default return value in case the file descriptor is invalid. -
The function
fdget
is called with thefile descriptor fd
to get a file structure associated with the file descriptor. This function performs various operations to obtain a reference to the file structure. -
If
f.file
(the file structure) is not null (i.e., a valid file structure is obtained), the function continues with the connection process. Otherwise, the default return value -EBADF is returned. -
The function
move_addr_to_kernel
is called to move the user-space sockaddr structure (uservaddr) to kernel space. This function ensures that the address structure is safely accessible in the kernel. The moved address is stored in the address variable of type structsockaddr_storage
. -
If
move_addr_to_kernel
succeeds (returns 0), the function__sys_connect_file
is called with the file structure, the address in kernel space (&address), theaddrlen
, and a flags parameter set to 0. This function performs the actual socket connection using the provided parameters. -
After the connection is attempted, the function
fdput
is called to release the file structure reference obtained by fdget. -
Finally, the
return value (ret)
is returned, which represents the result of the connection attempt. It will be either a negative error code (e.g., -EBADF if the file descriptor is invalid) or a non-negative value indicating success.
Description
If the socket sockfd
is of type SOCK_DGRAM
, then addr
is the address to which datagrams are sent by default, and the only address from which datagrams are received. If the socket is of type SOCK_STREAM
or SOCK_SEQPACKET
, this call attempts to make a connection to the socket that is bound to the address specified by addr
.
Some protocol sockets (e.g., UNIX domain
stream sockets) may successfully connect()
only once.
Some protocol sockets (e.g., datagram sockets
in the UNIX and Internet domains
) may use connect()
multiple times to change their association.
Some protocol sockets (e.g., TCP sockets as well as datagram sockets in the UNIX and Internet domains) may dissolve the association by connecting to an address with the sa_family member of sockaddr set to AF_UNSPEC; thereafter, the socket can be connected to another address. (AF_UNSPEC is supported on Linux since kernel 2.2.)