struct socket
{
socket_state state; // 该state用来表明该socket的当前状态
typedef enum {
SS_FREE = 0,
SS_UNCONNECTED,
SS_CONNECTING,
SS_CONNECTED,
SS_DISCONNECTING
} socket_state;
unsigned long flags; //该成员可能的值如下,该标志用来设置socket是否正在忙碌
#define SOCK_ASYNC_NOSPACE 0
#define SOCK_ASYNC_WAITDATA 1
#define SOCK_NOSPACE 2
struct proto_ops *ops; //依据协议邦定到该socket上的特定的协议族的操作函数指针
,例如IPv4 TCP就是inet_stream_ops
struct inode *inode; //表明该socket所属的inode
struct fasync_struct *fasync_list; //异步唤醒队列
struct file *file; //file回指指针
struct sock *sk; //sock指针
wait_queue_head_t wait; //sock的等待队列,在TCP需要等待时就sleep在这个队列上
short type; //表示该socket在特定协议族下的类型例如SOCK_STREAM,
unsigned char passcred; //在TCP分析中无须考虑
};
struct sock {
__u32 daddr; // dip,Foreign IPv4 addr
__u32 rcv_saddr; // 记录套接字所绑定的地址 Bound local IPv4 addr
__u16 dport; // dport
unsigned short num;
int bound_dev_if; // Bound device index if != 0
struct sock *next;
struct sock **pprev;
struct sock *bind_next;
struct sock **bind_pprev;
struct sock *prev;
volatile unsigned char state, zapped; // Connection state,zapped在TCP分析中无须考虑
__u16 sport; // 源端口,见num
unsigned short family; // 协议族,例如PF_INET
unsigned char reuse; // 地址是否可重用,只有RAW才使用
unsigned char shutdown; // 判断该socket连接在某方向或者双向方向上都已经关闭
#define SHUTDOWN_MASK 3
#define RCV_SHUTDOWN 1
#define SEND_SHUTDOWN 2
atomic_t refcnt; // 引用计数
socket_lock_t lock; // 锁标志, 每个socket都有一个自旋锁,该锁在用户上下文和软中断
处理时提供了同步机制
typedef struct {
spinlock_t slock;
unsigned int users;
wait_queue_head_t wq;
} socket_lock_t;
wait_queue_head_t *sleep; // Sock所属线程的自身休眠等待队列
struct dst_entry *dst_cache; // 目的地的路由缓存
rwlock_t dst_lock; // 为该socket赋dst_entry值时的锁
int rcvbuf; // 接受缓冲区的大小(按字节)
int sndbuf; // 发送缓冲区的大小(按字节)
atomic_t rmem_alloc; // 接受队列中存放的数据的字节数
atomic_t wmem_alloc; // 发送队列中存放的数据的字节数
int wmem_queued; // 所有已经发送的数据的总字节数
int forward_alloc; // 预分配剩余字节数
struct sk_buff_head receive_queue; // 接受队列
struct sk_buff_head write_queue; // 发送队列
atomic_t omem_alloc; // 在TCP分析中无须考虑 * "o" is "option" or "other" */
__u32 saddr;
unsigned int allocation; // 分配该sock之skb时选择的模式,GFP_ATOMIC还是
GFP_KERNEL等等
volatile char dead, // tcp_close.tcp_listen_stop.inet_sock_release调用sock_orphan将
该值置1,表示该socket已经和进程分开,变成孤儿
done, // 用于判断该socket是否已经收到 fin,如果收到则将该成员置1
urginline, // 如果该值被设置为1,表示将紧急数据放于普通数据流中一起处理,而不在另
外处理
keepopen, // 是否启动保活定时器
linger, // lingertime一起,指明了close()后保留的时间
destroy, // 在TCP分析中无须考虑
no_check, // 是否对发出的skb做校验和,仅对UDP有效
broadcast, // 是否允许广播,仅对UPD有效
bsdism; // 在TCP分析中无须考虑
unsigned char debug; // 在TCP分析中无须考虑
unsigned char rcvtstamp; // 是否将收到skb的时间戳发送给app
unsigned char use_write_queue; // 在init中该值被初始化为1,该值一直没有变化
unsigned char userlocks; // 包括如下几种值的组合,从而改变收包等操作的执行顺序
#define SOCK_SNDBUF_LOCK 1
#define SOCK_RCVBUF_LOCK 2
#define SOCK_BINDADDR_LOCK 4
#define SOCK_BINDPORT_LOCK 8
int route_caps; // 指示本sock用到的路由的信息
int proc; // 保存用户线程的pid
unsigned long lingertime; // lingertime一起,指明了close()后保留的时间
int hashent; // 存放4元的hash值
struct sock *pair; // 在TCP分析中无须考虑
struct {
struct sk_buff *head;
struct sk_buff *tail;
} backlog;
rwlock_t callback_lock; // sock相关函数内部操作的保护锁
struct sk_buff_head error_queue; // 错误报文的队列,很少使用
struct proto *prot; // 例如指向tcp_prot
union { // 私有TCP相关数据保存
struct tcp_opt af_tcp;
.............
} tp_pinfo;
int err, // 保存各种错误,例如ECONNRESET Connection reset by peer,从而会影响到后续
流程的处理
err_soft; // 保存各种软错误,例如EPROTO Protocol error,从而会影响到后续流程的处
理
unsigned short ack_backlog; // 当前已经accept的数目
unsigned short max_ack_backlog; // 当前listen sock能保留多少个待处理TCP连接.
__u32 priority;
unsigned short type; // 例如SOCK_STREAM,SOCK_DGRAM或者SOCK_RAW等
unsigned char localroute; // Route locally only if set – set by SO_DONTROUTE
option.
unsigned char protocol; // socket(int family, int type, int protocol)中的
protocol
struct ucred peercred; // 在TCP分析中无须考虑
int rcvlowat;
long rcvtimeo; // 接收时的超时设定, 并在超时时报错
long sndtimeo; // 发送时的超时设定, 并在超时时报错
union { // 私有inet相关数据保存
struct inet_opt af_inet;
.................
} protinfo;
struct timer_list timer;
struct timeval stamp;
struct socket *socket; // 对应的socket
void *user_data; // 私有数据,在TCP分析中无须考虑
void (*state_change)(struct sock *sk);
void (*data_ready)(struct sock *sk,int bytes);
void (*write_space)(struct sock *sk);
void (*error_report)(struct sock *sk);
int (*backlog_rcv) (struct sock *sk, struct sk_buff *skb);
void (*destruct)(struct sock *sk);
};
struct inet_opt
{
int ttl; // IP的TTL设置
int tos; // IP的TOS设置
unsigned cmsg_flags; // 该标志用来决定是否向应用层打印相关信息,包括如下可能
的值
#define IP_CMSG_PKTINFO 1
#define IP_CMSG_TTL 2
#define IP_CMSG_TOS 4
#define IP_CMSG_RECVOPTS 8
#define IP_CMSG_RETOPTS 16
struct ip_options *opt; // IP选项,包括安全和处理限制、记录路径、时间戳、宽松的
源站选路、严格的源站选路
unsigned char hdrincl; // 用于RAW
__u8 mc_ttl; // 多播TTL
__u8 mc_loop; // 多播回环
unsigned recverr : 1, // 是否允许传递扩展的可靠的错误信息.
freebind : 1; // 是否允许socket被绑定
__u16 id; // 用于禁止分片的IP包的ID计数
__u8 pmtudisc; // 路径MTU发现
int mc_index; // 多播设备索引
__u32 mc_addr; // 自己的多播地址
struct ip_mc_socklist *mc_list; // 多播组
};
struct tcp_opt {
int tcp_header_len; // tcp首部长度(包括选项)
__u32 pred_flags;
__u32 rcv_nxt; // 期望接受到的下一个tcp包的seq
__u32 snd_nxt; // 要发送的下一个tcp包的seq
__u32 snd_una; // 表示最近一个尚未确认的但是已经发送过的报文的seq
__u32 snd_sml; // 最近发送的小包的最后一个字节数,主要用于Nagle算法
__u32 rcv_tstamp; // 最近收到的ACK的时间,用于保活
__u32 lsndtime; // 最近发送的数据包的时间,用于窗口restart
struct {
__u8 pending;
enum tcp_ack_state_t
{
TCP_ACK_SCHED = 1,
TCP_ACK_TIMER = 2,
TCP_ACK_PUSHED= 4
};
__u8 quick;
__u8 pingpong;
__u8 blocked; ]
__u32 ato;
unsigned long timeout;
__u32 lrcvtime;
__u16 last_seg_size;
__u16 rcv_mss;
} ack;
__u16 mss_cache; // 当前提供的有效mss,
__u16 mss_clamp; // 最大mss,连接建立时协商的mss或者用户通过ioctl指定的mss的两者
之中最大值
__u16 advmss;
struct {
struct sk_buff_head prequeue; // 当前预备队列
struct task_struct *task; // 当前线程
struct iovec *iov; // 用户空间接受数据的地址
int memory; // 当前预备队列中的包总字节数目
int len; // 用户进程从预备队列中读取的数据字节数
} ucopy;
__u32 snd_wl1; // 收到对方返回的skb,记下该包的seq号,用于判断窗口是否需要更新
__u32 snd_wnd; // 记录对方提供的窗口大小
__u32 max_window; // 对方曾经提供的最大窗口
__u32 pmtu_cookie; // 将发送mss和当前的pmtu/exthdr设置同步
__u16 ext_header_len; // 网络层协议选项长度
__u8 ca_state; // 快速重传状态机
enum tcp_ca_state
{
TCP_CA_Open = 0,
TCP_CA_Disorder = 1,
TCP_CA_CWR = 2,
TCP_CA_Recovery = 3,
TCP_CA_Loss = 4
};
__u8 retransmits; // 某个还没有被确认的发送TCP包重传的次数
__u8 reordering;
__u8 queue_shrunk;
__u8 defer_accept; // 请参考附录1
__u8 backoff;
__u32 srtt;
__u32 mdev;
__u32 mdev_max;
__u32 rttvar;
__u32 rtt_seq;
__u32 rto;
__u32 packets_out;
__u32 left_out;
__u32 retrans_out;
// 慢启动和拥塞控制 Slow start and congestion control (see also Nagle, and Karn &
Partridge)
__u32 snd_ssthresh; // 拥塞控制时的慢启动门限
__u32 snd_cwnd; // 当前采用的拥塞窗口
__u16 snd_cwnd_cnt; // 线形增加的拥塞窗口计数器
__u16 snd_cwnd_clamp; // 拥塞窗口的最大值(一般为对方通告的窗口大小)
__u32 snd_cwnd_used; // 慢启动,每发出去一个包,snd_cwnd_used++
__u32 snd_cwnd_stamp; // 该参数可以保证在重传模式下不会改变拥塞窗口的大小 */
unsigned long timeout; // 用于重传
struct timer_list retransmit_timer;
struct timer_list delack_timer;
struct sk_buff_head out_of_order_queue; // 乱序的TCP报都存放在该队列中
struct tcp_func *af_specific; // ipv4/ipv6 相关特定处理函数
struct tcp_func ipv4_specific = {
ip_queue_xmit,
tcp_v4_send_check,
tcp_v4_rebuild_header,
tcp_v4_conn_request,
tcp_v4_syn_recv_sock,
tcp_v4_remember_stamp,
sizeof(struct iphdr),
ip_setsockopt,
ip_getsockopt,
v4_addr2sockaddr,
sizeof(struct sockaddr_in)
};
struct sk_buff *send_head; // 最先要发送的TCP报文
struct page *sndmsg_page; // sendmsg所使用的缓冲内存页面
u32 sndmsg_off; // sendmsg所使用的缓冲偏移
__u32 rcv_wnd; // 当前接受窗口
__u32 rcv_wup; // 对方窗口最后一次更新时的rcv_nxt
__u32 write_seq; // tcp发送总数据字节量+1
__u32 pushed_seq; // 上次发送带PSH标志的TCP包的seq
__u32 copied_seq; // 尚未读取的数据第一个字节位置
// Options received (usually on last packet, some only on SYN packets).
char tstamp_ok,
wscale_ok,
sack_ok;
char saw_tstamp;
__u8 snd_wscale;
__u8 rcv_wscale;
__u8 nonagle;
__u8 keepalive_probes;
__u32 rcv_tsval;
__u32 rcv_tsecr;
__u32 ts_recent;
long ts_recent_stamp;
__u16 user_mss;
__u8 dsack;
__u8 eff_sacks;
struct tcp_sack_block duplicate_sack[1];
struct tcp_sack_block selective_acks[4];
__u32 window_clamp;
__u32 rcv_ssthresh;
__u8 probes_out;
__u8 num_sacks;
__u8 syn_retries;
__u8 ecn_flags;
__u16 prior_ssthresh;
__u32 lost_out;
__u32 sacked_out;
__u32 fackets_out;
__u32 high_seq;
__u32 retrans_stamp; // 上次重传的时间,其也会记住第一个syn的时间戳
__u32 undo_marker;
int undo_retrans;
__u32 urg_seq;
__u16 urg_data;
__u8 pending;
#define TCP_TIME_RETRANS 1
#define TCP_TIME_DACK 2
#define TCP_TIME_PROBE0 3
#define TCP_TIME_KEEPOPEN 4
__u8 urg_mode;
__u32 snd_up;
rwlock_t syn_wait_lock;
struct tcp_listen_opt *listen_opt;
struct open_request *accept_queue;
struct open_request *accept_queue_tail;
int write_pending;
unsigned int keepalive_time;
unsigned int keepalive_intvl;
int linger2; // lingertime一起,指明了close()后保留的时间
int frto_counter;
__u32 frto_highmark;
unsigned long last_synq_overflow; // 用于syn_cookie处理
};