📄 tcp.h
字号:
static inline void tcp_set_state(struct sock *sk, int state){ int oldstate = sk->sk_state; switch (state) { case TCP_ESTABLISHED: if (oldstate != TCP_ESTABLISHED) TCP_INC_STATS(TCP_MIB_CURRESTAB); break; case TCP_CLOSE: if (oldstate == TCP_CLOSE_WAIT || oldstate == TCP_ESTABLISHED) TCP_INC_STATS(TCP_MIB_ESTABRESETS); sk->sk_prot->unhash(sk); if (inet_csk(sk)->icsk_bind_hash && !(sk->sk_userlocks & SOCK_BINDPORT_LOCK)) inet_put_port(&tcp_hashinfo, sk); /* fall through */ default: if (oldstate==TCP_ESTABLISHED) TCP_DEC_STATS(TCP_MIB_CURRESTAB); } /* Change state AFTER socket is unhashed to avoid closed * socket sitting in hash tables. */ sk->sk_state = state;#ifdef STATE_TRACE SOCK_DEBUG(sk, "TCP sk=%p, State %s -> %s\n",sk, statename[oldstate],statename[state]);#endif }extern void tcp_done(struct sock *sk);static inline void tcp_sack_reset(struct tcp_options_received *rx_opt){ rx_opt->dsack = 0; rx_opt->eff_sacks = 0; rx_opt->num_sacks = 0;}/* Determine a window scaling and initial window to offer. */extern void tcp_select_initial_window(int __space, __u32 mss, __u32 *rcv_wnd, __u32 *window_clamp, int wscale_ok, __u8 *rcv_wscale);static inline int tcp_win_from_space(int space){ return sysctl_tcp_adv_win_scale<=0 ? (space>>(-sysctl_tcp_adv_win_scale)) : space - (space>>sysctl_tcp_adv_win_scale);}/* Note: caller must be prepared to deal with negative returns */ static inline int tcp_space(const struct sock *sk){ return tcp_win_from_space(sk->sk_rcvbuf - atomic_read(&sk->sk_rmem_alloc));} static inline int tcp_full_space(const struct sock *sk){ return tcp_win_from_space(sk->sk_rcvbuf); }static inline void tcp_openreq_init(struct request_sock *req, struct tcp_options_received *rx_opt, struct sk_buff *skb){ struct inet_request_sock *ireq = inet_rsk(req); req->rcv_wnd = 0; /* So that tcp_send_synack() knows! */ tcp_rsk(req)->rcv_isn = TCP_SKB_CB(skb)->seq; req->mss = rx_opt->mss_clamp; req->ts_recent = rx_opt->saw_tstamp ? rx_opt->rcv_tsval : 0; ireq->tstamp_ok = rx_opt->tstamp_ok; ireq->sack_ok = rx_opt->sack_ok; ireq->snd_wscale = rx_opt->snd_wscale; ireq->wscale_ok = rx_opt->wscale_ok; ireq->acked = 0; ireq->ecn_ok = 0; ireq->rmt_port = tcp_hdr(skb)->source;}extern void tcp_enter_memory_pressure(void);static inline int keepalive_intvl_when(const struct tcp_sock *tp){ return tp->keepalive_intvl ? : sysctl_tcp_keepalive_intvl;}static inline int keepalive_time_when(const struct tcp_sock *tp){ return tp->keepalive_time ? : sysctl_tcp_keepalive_time;}static inline int tcp_fin_time(const struct sock *sk){ int fin_timeout = tcp_sk(sk)->linger2 ? : sysctl_tcp_fin_timeout; const int rto = inet_csk(sk)->icsk_rto; if (fin_timeout < (rto << 2) - (rto >> 1)) fin_timeout = (rto << 2) - (rto >> 1); return fin_timeout;}static inline int tcp_paws_check(const struct tcp_options_received *rx_opt, int rst){ if ((s32)(rx_opt->rcv_tsval - rx_opt->ts_recent) >= 0) return 0; if (get_seconds() >= rx_opt->ts_recent_stamp + TCP_PAWS_24DAYS) return 0; /* RST segments are not recommended to carry timestamp, and, if they do, it is recommended to ignore PAWS because "their cleanup function should take precedence over timestamps." Certainly, it is mistake. It is necessary to understand the reasons of this constraint to relax it: if peer reboots, clock may go out-of-sync and half-open connections will not be reset. Actually, the problem would be not existing if all the implementations followed draft about maintaining clock via reboots. Linux-2.2 DOES NOT! However, we can relax time bounds for RST segments to MSL. */ if (rst && get_seconds() >= rx_opt->ts_recent_stamp + TCP_PAWS_MSL) return 0; return 1;}#define TCP_CHECK_TIMER(sk) do { } while (0)static inline void tcp_mib_init(void){ /* See RFC 2012 */ TCP_ADD_STATS_USER(TCP_MIB_RTOALGORITHM, 1); TCP_ADD_STATS_USER(TCP_MIB_RTOMIN, TCP_RTO_MIN*1000/HZ); TCP_ADD_STATS_USER(TCP_MIB_RTOMAX, TCP_RTO_MAX*1000/HZ); TCP_ADD_STATS_USER(TCP_MIB_MAXCONN, -1);}/* from STCP */static inline void tcp_clear_retrans_hints_partial(struct tcp_sock *tp){ tp->lost_skb_hint = NULL; tp->scoreboard_skb_hint = NULL; tp->retransmit_skb_hint = NULL; tp->forward_skb_hint = NULL;}static inline void tcp_clear_all_retrans_hints(struct tcp_sock *tp){ tcp_clear_retrans_hints_partial(tp); tp->fastpath_skb_hint = NULL;}/* MD5 Signature */struct crypto_hash;/* - key database */struct tcp_md5sig_key { u8 *key; u8 keylen;};struct tcp4_md5sig_key { struct tcp_md5sig_key base; __be32 addr;};struct tcp6_md5sig_key { struct tcp_md5sig_key base;#if 0 u32 scope_id; /* XXX */#endif struct in6_addr addr;};/* - sock block */struct tcp_md5sig_info { struct tcp4_md5sig_key *keys4;#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) struct tcp6_md5sig_key *keys6; u32 entries6; u32 alloced6;#endif u32 entries4; u32 alloced4;};/* - pseudo header */struct tcp4_pseudohdr { __be32 saddr; __be32 daddr; __u8 pad; __u8 protocol; __be16 len;};struct tcp6_pseudohdr { struct in6_addr saddr; struct in6_addr daddr; __be32 len; __be32 protocol; /* including padding */};union tcp_md5sum_block { struct tcp4_pseudohdr ip4;#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) struct tcp6_pseudohdr ip6;#endif};/* - pool: digest algorithm, hash description and scratch buffer */struct tcp_md5sig_pool { struct hash_desc md5_desc; union tcp_md5sum_block md5_blk;};#define TCP_MD5SIG_MAXKEYS (~(u32)0) /* really?! *//* - functions */extern int tcp_v4_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key, struct sock *sk, struct dst_entry *dst, struct request_sock *req, struct tcphdr *th, int protocol, int tcplen);extern struct tcp_md5sig_key *tcp_v4_md5_lookup(struct sock *sk, struct sock *addr_sk);extern int tcp_v4_md5_do_add(struct sock *sk, __be32 addr, u8 *newkey, u8 newkeylen);extern int tcp_v4_md5_do_del(struct sock *sk, __be32 addr);extern struct tcp_md5sig_pool **tcp_alloc_md5sig_pool(void);extern void tcp_free_md5sig_pool(void);extern struct tcp_md5sig_pool *__tcp_get_md5sig_pool(int cpu);extern void __tcp_put_md5sig_pool(void);static inlinestruct tcp_md5sig_pool *tcp_get_md5sig_pool(void){ int cpu = get_cpu(); struct tcp_md5sig_pool *ret = __tcp_get_md5sig_pool(cpu); if (!ret) put_cpu(); return ret;}static inline void tcp_put_md5sig_pool(void){ __tcp_put_md5sig_pool(); put_cpu();}/* write queue abstraction */static inline void tcp_write_queue_purge(struct sock *sk){ struct sk_buff *skb; while ((skb = __skb_dequeue(&sk->sk_write_queue)) != NULL) sk_stream_free_skb(sk, skb); sk_stream_mem_reclaim(sk);}static inline struct sk_buff *tcp_write_queue_head(struct sock *sk){ struct sk_buff *skb = sk->sk_write_queue.next; if (skb == (struct sk_buff *) &sk->sk_write_queue) return NULL; return skb;}static inline struct sk_buff *tcp_write_queue_tail(struct sock *sk){ struct sk_buff *skb = sk->sk_write_queue.prev; if (skb == (struct sk_buff *) &sk->sk_write_queue) return NULL; return skb;}static inline struct sk_buff *tcp_write_queue_next(struct sock *sk, struct sk_buff *skb){ return skb->next;}#define tcp_for_write_queue(skb, sk) \ for (skb = (sk)->sk_write_queue.next; \ (skb != (struct sk_buff *)&(sk)->sk_write_queue); \ skb = skb->next)#define tcp_for_write_queue_from(skb, sk) \ for (; (skb != (struct sk_buff *)&(sk)->sk_write_queue);\ skb = skb->next)static inline struct sk_buff *tcp_send_head(struct sock *sk){ return sk->sk_send_head;}static inline void tcp_advance_send_head(struct sock *sk, struct sk_buff *skb){ struct tcp_sock *tp = tcp_sk(sk); sk->sk_send_head = skb->next; if (sk->sk_send_head == (struct sk_buff *)&sk->sk_write_queue) sk->sk_send_head = NULL; /* Don't override Nagle indefinately with F-RTO */ if (tp->frto_counter == 2) tp->frto_counter = 3;}static inline void tcp_check_send_head(struct sock *sk, struct sk_buff *skb_unlinked){ if (sk->sk_send_head == skb_unlinked) sk->sk_send_head = NULL;}static inline void tcp_init_send_head(struct sock *sk){ sk->sk_send_head = NULL;}static inline void __tcp_add_write_queue_tail(struct sock *sk, struct sk_buff *skb){ __skb_queue_tail(&sk->sk_write_queue, skb);}static inline void tcp_add_write_queue_tail(struct sock *sk, struct sk_buff *skb){ __tcp_add_write_queue_tail(sk, skb); /* Queue it, remembering where we must start sending. */ if (sk->sk_send_head == NULL) sk->sk_send_head = skb;}static inline void __tcp_add_write_queue_head(struct sock *sk, struct sk_buff *skb){ __skb_queue_head(&sk->sk_write_queue, skb);}/* Insert buff after skb on the write queue of sk. */static inline void tcp_insert_write_queue_after(struct sk_buff *skb, struct sk_buff *buff, struct sock *sk){ __skb_append(skb, buff, &sk->sk_write_queue);}/* Insert skb between prev and next on the write queue of sk. */static inline void tcp_insert_write_queue_before(struct sk_buff *new, struct sk_buff *skb, struct sock *sk){ __skb_insert(new, skb->prev, skb, &sk->sk_write_queue); if (sk->sk_send_head == skb) sk->sk_send_head = new;}static inline void tcp_unlink_write_queue(struct sk_buff *skb, struct sock *sk){ __skb_unlink(skb, &sk->sk_write_queue);}static inline int tcp_skb_is_last(const struct sock *sk, const struct sk_buff *skb){ return skb->next == (struct sk_buff *)&sk->sk_write_queue;}static inline int tcp_write_queue_empty(struct sock *sk){ return skb_queue_empty(&sk->sk_write_queue);}/* /proc */enum tcp_seq_states { TCP_SEQ_STATE_LISTENING, TCP_SEQ_STATE_OPENREQ, TCP_SEQ_STATE_ESTABLISHED, TCP_SEQ_STATE_TIME_WAIT,};struct tcp_seq_afinfo { struct module *owner; char *name; sa_family_t family; int (*seq_show) (struct seq_file *m, void *v); struct file_operations *seq_fops;};struct tcp_iter_state { sa_family_t family; enum tcp_seq_states state; struct sock *syn_wait_sk; int bucket, sbucket, num, uid; struct seq_operations seq_ops;};extern int tcp_proc_register(struct tcp_seq_afinfo *afinfo);extern void tcp_proc_unregister(struct tcp_seq_afinfo *afinfo);extern struct request_sock_ops tcp_request_sock_ops;extern int tcp_v4_destroy_sock(struct sock *sk);extern int tcp_v4_gso_send_check(struct sk_buff *skb);extern struct sk_buff *tcp_tso_segment(struct sk_buff *skb, int features);#ifdef CONFIG_PROC_FSextern int tcp4_proc_init(void);extern void tcp4_proc_exit(void);#endif/* TCP af-specific functions */struct tcp_sock_af_ops {#ifdef CONFIG_TCP_MD5SIG struct tcp_md5sig_key *(*md5_lookup) (struct sock *sk, struct sock *addr_sk); int (*calc_md5_hash) (char *location, struct tcp_md5sig_key *md5, struct sock *sk, struct dst_entry *dst, struct request_sock *req, struct tcphdr *th, int protocol, int len); int (*md5_add) (struct sock *sk, struct sock *addr_sk, u8 *newkey, u8 len); int (*md5_parse) (struct sock *sk, char __user *optval, int optlen);#endif};struct tcp_request_sock_ops {#ifdef CONFIG_TCP_MD5SIG struct tcp_md5sig_key *(*md5_lookup) (struct sock *sk, struct request_sock *req);#endif};extern void tcp_v4_init(struct net_proto_family *ops);extern void tcp_init(void);#endif /* _TCP_H */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -