プロセスとシステムを実行している呼び出し元のプロセスのTCPプロトコルの深い理解

プロセスとシステムを実行している呼び出し元のプロセスのTCPプロトコルの深い理解

実験は、主に以下の分野での開発します:

  1. TCP / IPの階層
  2. システムコールを実行しているプロセスのTCPプロトコル
  3. 追跡検証

A、TCP / IPの階層

私は、すべてのテストが少なすぎる研究パートナー階層構造TCP / IPモデルは確かには見知らぬ人ではないと信じています。私たちの学部の研究では、実際には、ネットワークモデルの構造は、7層のIEEE定義を5層構造を学習すると、実際のアプリケーションでは4層構造である一方で、4層である:アプリケーション層、トランスポート層、インターネット層、ネットワークインターフェース層。ここで私は比較チャート4、5と7層構造をまとめ、少し相手が見ることができますが、忘れています。以下の

第二に、TCPプロトコルのシステムコールを実行するプロセス

一般的には、TCPプロトコルを実行するプロセスは、合計する「スリーウェイハンドシェイク」と「4波」を使用することができます

  • TCPプロトコル「3ウェイハンドシェイク」

    (1)最初のハンドシェーク:
    クライアントSYNフラグビットがランダムに生成された値の配列= J、1に設定され、パケットがサーバーに送信され、クライアントが肯定応答サーバを待って、SYN_SENT状態に入ります。
    (2)第二のハンドシェイク:
    サーバフラグSYN接続を確立するため= 1つの既知のクライアント要求からのデータパケットを受信した後、サーバSYNとACKフラグビットがACK = J + 1、ランダムに生成された値の配列= 1に設定されていますK、およびクライアントに接続要求を確認するためにデータパケットを送信し、サーバーがSYN_RCVD状態に入ります。
    (3)第三のハンドシェーク:
    クライアントがACK J + 1は、ACK 1、正しいACKフラグが1に設定されている場合、ACK = K + 1であり、データパケットか否かを確認する、確認応答を受信しますサーバーに、サーバーをチェックしたack K + 1かどうかを、ACKは1、正しい場合は、接続が確立され、クライアントであり、サーバは、3ウェイハンドシェイクを完了し、あなたがクライアントとサーバー間のデータ転送を開始することができ、状態を確立して入ります。

  • TCPプロトコル「4波」

    (1)クライアントがクライアントサーバー入札者へのデータ転送を閉じるため、FINを送信し、クライアントがFIN_WAIT_1状態に入ります。

    (2)Server收到FIN后,发送一个ACK给Client,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),Server进入CLOSE_WAIT状态。

    (3)Server发送一个FIN,用来关闭Server到Client的数据传送,Server进入LAST_ACK状态。

    (4)Client收到FIN后,Client进入TIME_WAIT状态,接着发送一个ACK给Server,确认序号为收到序号+1,Server进入CLOSED状态,完成四次挥手。

  • TCP的运行过程的转态转换

我们从上图的转态转换以及上次实验的结果得出,典型的TCP客户端和服务器应用程序发出一系列TCP系统调用以实现某些功能,这些系统调用包括socket()、bind()、listen()、accept()、connect()、send()、receieve()、close()、shutdown()。当TCP应用运行的时候,会发生如下的事情:

  1. 首先,套接字接受进行的任何TCP系统调用。套接字层验证TCP应用程序传递的参数的正确性。
  2. 套接字层下面是协议层,其中包含协议的实际实现。当套接字层对协议层进行调用时,它确保对两个层之间共享的 数据结构具有独占访问权限。这样做是为了避免任何数据结构损坏。
  3. 各种网络设备驱动程序运行在接口层,该接口从数据链路层接受数据并向物理链路传输数据。

Socket

socket (struct proc ∗p, struct socket_args ∗uap, int retval)   
struct sock_args 
{
int domain, 
int type,
int protocol;
};

在socket系统调用中 :

  • p是指向socket调用的进程proc结构的指针
  • uap是指向socket_args结构的指针,该结构包含在socket系统调用中传递给进程的参数
  • retval是系统调用的返回值

socket系统调用创建通过分配新的描述符来创建新的套接字。新的描述符返回到调用过程。任何后续的系统调用都使用创建的套接字标识。套接字系统调用还将协议分配给创建的套接字描述符。domain,type和protocol参数值指定要分配给创建的套接字的族,类型和协议。

Bind

bind (struct proc ∗p, struct bind_args ∗uap, int ∗retval)   
struct bind_args 
{   int s;
    caddr_t name;
    int namelen;
};

bind系统调用中:

  • 是套接字描述符
  • name是指向包含网络传输地址的缓冲区的指针
  • namelen代表缓冲区的大小

bind系统调用将本地网络传输地址与套接字相关联。当客户端进程发出连接系统调用使,内核负责进行隐式绑定。服务器进程通常必须发出明确的绑定请求,然后才能接受连接或开始于客户端的通信

Listen

listen (struct proc ∗p, struct listen_args ∗uap, int ∗retval);     
struct listen_args
{ int s;
int backlog;
};

listen系统调用中:

  • s是套接字描述符
  • backlog是套接字上连接数的队列限制

listen系统调用向协议指示服务器进程已准备好接受套接字上的任何新的传入连接。但是可以排队的连接数有限制,在此之后,任何其他连接请求都将被忽略。

Accept

accept(struct proc ∗p, struct accept_args ∗uap, int ∗retval);   
struct  accept_args 
{
    int s;
    caddr_t name;
    int ∗anamelen;
};

listen系统调用中:

  • s是套接字描述符
  • name 是一个缓冲区,其中包含外部主机的网络传输地址
  • anamelen是name缓冲区的大小

accept系统调用是等待传入连接的阻塞调用。一旦处理了连接请求,accept将返回一个新的套接字描述符。这个新的套接字已连接到客户端,其他套接字仍保持LISTEN状态以接受进一步的连接

Connect

connect (struct proc ∗p, struct connect_args ∗uap, int ∗retval);   
struct connect_args 
{
    int s;
    caddr_t name;
    int namelen;
};

connect系统调用:

  • s是套接字描述符
  • name是指向具有外部IP /端口地址对的缓冲区的指针
  • namelen是缓冲的大小

客户端进程通常会调用connect系统调用以连接到服务器进程。如果客户端进程在启动连接之前未显式发出bind系统调用,则堆栈将处理本地套接字上的隐式绑定。

Shutdown

shutdown (struct proc ∗p, struct shutdown_args ∗uap, int ∗retval);   
Struct shutdown_args
{
    int s;
    int how;
}

shutdown系统调用中:

  • s是套接字描述符
  • how指定要关闭连接的哪一端。值分别为0,1,2,分别用于指定如何关闭从客户端到服务端的连接,从服务端向客户端的连接,或者把两个连接都关闭。

shutdown系统调用将关闭连接的一端或两端。如果需要关闭的是服务端指向客户端的连接,那么将丢弃接收缓冲区中存在的所有数据,并关闭连接的那一端。如果关闭的是客户端指向服务端的连接,TCP发送所有剩余数据,然后终止连接的写端

Close

soo_close(struct file ∗fp , struct proc ∗p);  

close系统调用中:

  • fp是指向文件结构的指针
  • p是指向调用过程的proc结构的指针

close系统调用将关闭或终止套接字上的所有挂起的连接

Send

sendmsg ( struct proc∗p, struct sendmsg_args ∗uap, int retval);   
struct sendmsg_args
{    
   int s;
   caddr_t msg;
   int flags;
};

send系统调用中:

  • s是套接字描述符
  • msg是指向msghdr结构的指针
  • flags是控制信息

Receieve

recvmsg(struct proc ∗p, struct recvmsg_args ∗uap , int ∗retval);   
struct recvmsg_args 
{
 int s,
 struct msghdr ∗msg,
 int flags,
};

Receieve系统调用中

  • s 是套接字描述符
  • msg是指向msghdr结构的指针
  • flags是控制信息

三、跟踪验证

  1. 首先,在启动qemuqemu -kernel linux-5.0.1/arch/x86/boot/bzImage -initrd rootfs.img -append nokaslr -s -S
  2. 然后另开一个命令行输入gdb,进入调试模式,然后输入file linux-5.0.1/vmlinux加载符号表,
  3. 设置断点。按照上面的分析,如下图所示
  4. 输入target remote:1234建立连接
  5. 不停的按c回车运行,直到运行结束。
    运行结果如下图所示:

结合上面的tcp运行过程和以及实际跟踪情况来看,会调用socket系统调用,这个系统调用对应着 sys_connectsys_accept,这两个函数又对应着刚刚我们设置短点的函数tcp_v4_connectinet_csk_accept函数。
inet_csk_accept函数会从客户端发出的请求中取出一个请求,如果没有客户端发出连接请求,那么服务端就会调用inet_csk_wait_for_connet函数并阻塞监听端口,等待客户端发出连接请求。
除了上面这个,服务端还会使用到sys_socket,sys_socket在其内部又调用了socket_create用于创建套接字
一旦请求来到,服务端就会调用sys_connect ,这个函数又会调用inet_csk_accept函数,这个函
tcp_v4_connect函数用于发起一个tcp连接请求,主要是客户端会调用这个

实验参考:
https://developer.ibm.com/articles/au-tcpsystemcalls/
https://github.com/mengning/net/tree/master

おすすめ

転載: www.cnblogs.com/sa19225475/p/12104647.html