当前位置:网站首页>The role of connect in the network
The role of connect in the network
2022-06-22 11:15:00 【To maintain world peace_】
Catalog
connect effect
The client is executing connect when ,
- The local socket The state is set to TCP_SYN_SENT
- Select an available port , issue SYN Handshake request and reset timer
Function call relationship
connect -> __sys_connect-> __sys_connect_file
int __sys_connect_file(struct file *file, struct sockaddr_storage *address,
int addrlen, int file_flags)
{
// according to file lookup sock object
sock = sock_from_file(file, &err);
if (!sock)
goto out;
//connect
err = sock->ops->connect(sock, (struct sockaddr *)address, addrlen,
sock->file->f_flags | file_flags);
}
inet_stream_connect
int inet_stream_connect(struct socket *sock, struct sockaddr *uaddr,
int addr_len, int flags)
{
err = __inet_stream_connect(sock, uaddr, addr_len, flags, 0);
}
int __inet_stream_connect(struct socket *sock, struct sockaddr *uaddr,
int addr_len, int flags, int is_sendmsg)
{
// Just created socket state SS_UNCONNECTED
case SS_UNCONNECTED:
if (sk->sk_state != TCP_CLOSE)
goto out;
err = sk->sk_prot->connect(sk, uaddr, addr_len);
sock->state = SS_CONNECTING;
break;
}
}
tcp_v4_connect
int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
{
// Set up socket state TCP_SYN_SENT
tcp_set_state(sk, TCP_SYN_SENT);
// Dynamically select a port
err = inet_hash_connect(tcp_death_row, sk);
// according to sk Information in , Construct a SYNC Message of , And send it out
err = tcp_connect(sk);
}inet_hash_connect
int __inet_hash_connect(struct inet_timewait_death_row *death_row,
struct sock *sk, u32 port_offset,
int (*check_established)(struct inet_timewait_death_row *,
struct sock *, __u16, struct inet_timewait_sock **))
{
int port = inet_sk(sk)->inet_num;// Get port
// Whether to bind ports
if (port) {
head = &hinfo->bhash[inet_bhashfn(net, port,
hinfo->bhash_size)];
tb = inet_csk(sk)->icsk_bind_hash;
spin_lock_bh(&head->lock);
if (sk_head(&tb->owners) == sk && !sk->sk_bind_node.next) {
inet_ehash_nolisten(sk, NULL);
spin_unlock_bh(&head->lock);
return 0;
}
spin_unlock(&head->lock);
ret = check_established(death_row, sk, port, NULL);
local_bh_enable();
return ret;
}
l3mdev = inet_sk_bound_l3mdev(sk);
// Get local port configuration
inet_get_local_port_range(net, &low, &high);
high++; /* [32768, 60999] -> [32768, 61000[ */
remaining = high - low;
if (likely(remaining > 1))
remaining &= ~1U;
offset = (hint + port_offset) % remaining;
offset &= ~1U;
other_parity_scan:
port = low + offset;// How to determine the port availability
for (i = 0; i < remaining; i += 2, port += 2) {
if (unlikely(port >= high))
port -= remaining;
// Whether it is reserved port , net.ipv4.ip_local_reversed_ports
if (inet_is_local_reserved_port(net, port))
continue;
// Find the port that has been used hash surface
head = &hinfo->bhash[inet_bhashfn(net, port,
hinfo->bhash_size)];
spin_lock_bh(&head->lock);
inet_bind_bucket_for_each(tb, &head->chain) {
// If the port is used
if (net_eq(ib_net(tb), net) && tb->l3mdev == l3mdev &&
tb->port == port) {
if (tb->fastreuse >= 0 ||
tb->fastreuseport >= 0)
goto next_port;
WARN_ON(hlist_empty(&tb->owners));
// Check whether it is available to continue using , Check whether the quads are the same
if (!check_established(death_row, sk,
port, &tw))
goto ok;
goto next_port;
}
}
// Not used
tb = inet_bind_bucket_create(hinfo->bind_bucket_cachep,
net, head, port, l3mdev);
if (!tb) {
spin_unlock_bh(&head->lock);
return -ENOMEM;
}
tb->fastreuse = -1;
tb->fastreuseport = -1;
goto ok;
next_port:
spin_unlock_bh(&head->lock);
cond_resched();
}
return -EADDRNOTAVAIL;//cannot assign requested address
}
Key function analysis
- First judgement inet_sk(sk)->inet_num, If called bind, This function will select the port and set it in inet_num On . without bind,port by 0;
- inet_get_local_port_range This function gets net.ipv4.ip_local_port_range Kernel parameters ;
- inet_is_local_reserved_port Determine whether the port to be selected is in net.ipv4.ip_local_reserved_local_port in ;
- stay hash Find the port in the table , If not found, you can use ;inet_bind_bucket_for_each Apply for one inet_bind_bucket To record port usage , And use hash Form management ;
- If it has been used , adopt check_established Continue to test for availability , If you return 0 Is still available ;
- If not used , be inet_bind_bucket_create Create a
- If the port is not found , Then return to EADDRNOTAVAIL, Application layer tips Cannot assign requested address
// Check whether it is consistent with the existing ESTABLISH State connection conflict
static int __inet_check_established(struct inet_timewait_death_row *death_row,
struct sock *sk, __u16 lport,
struct inet_timewait_sock **twp)
{
// lookup hash
struct inet_ehash_bucket *head = inet_ehash_bucket(hinfo, hash);
// Find out if the quadruple has the same
sk_nulls_for_each(sk2, node, &head->chain) {
if (sk2->sk_hash != hash)
continue;
// Yes saddr,daddr,port Made a comparison
if (likely(INET_MATCH(sk2, net, acookie,
saddr, daddr, ports, dif, sdif))) {
if (sk2->sk_state == TCP_TIME_WAIT) {
tw = inet_twsk(sk2);
if (twsk_unique(sk, sk2, twp))
break;
}
goto not_unique;
}
}
return 0;// Available
not_unique:
return -EADDRNOTAVAIL;// There is nothing available
}
INET_MATCH Source code is as follows , take __saddr,__daddr,__ports All of them are compared . If it matches, the port cannot be used , If it doesn't match , Ports available .
#define INET_MATCH(__sk, __net, __cookie, __saddr, __daddr, __ports, __dif, __sdif) \
(((__sk)->sk_portpair == (__ports)) && \
((__sk)->sk_daddr == (__saddr)) && \
((__sk)->sk_rcv_saddr == (__daddr)) && \
(((__sk)->sk_bound_dev_if == (__dif)) || \
((__sk)->sk_bound_dev_if == (__sdif))) && \
net_eq(sock_net(__sk), (__net)))
#endif /* 64-bit arch */tcp_connect
/* Build a SYN and send it off. */
int tcp_connect(struct sock *sk)
{
// apply skb
buff = sk_stream_alloc_skb(sk, 0, sk->sk_allocation, true);
// Add to send queue sk_write_queue
tcp_connect_queue_skb(sk, buff);
tcp_ecn_send_syn(sk, buff);
tcp_rbtree_insert(&sk->tcp_rtx_queue, buff);
// send out syn tcp_transmit_skb
err = tp->fastopen_req ? tcp_send_syn_data(sk, buff) :
tcp_transmit_skb(sk, buff, 1, sk->sk_allocation);
// Restart timer
/* Timer for repeating the SYN until an answer. */
inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS,
inet_csk(sk)->icsk_rto, TCP_RTO_MAX);
return 0;
}// Timeout time 1s
#define TCP_TIMEOUT_INIT ((unsigned)(1*HZ)) /* RFC6298 2.1 initial RTO value */
// On initialization Set the time
void tcp_init_sock(struct sock *sk)
{
..
icsk->icsk_rto = TCP_TIMEOUT_INIT;
}tcp_connect The role of
- apply skb, And set it to SKB package
- Add to send queue
- call tcp_transmit_skb Send the packet
- Restart timer , It will be resend after timeout
summary
- Cannot assign requested address An error that is issued when the port is not found available ; Can be adjusted by net.ipv4.ip_local_port_range Parameters , Release some ports ;
- If some ports do not want to be used , Kernel parameters ip_local_reserved_ports Set up .
Reference resources
https://course.0voice.com/v1/course/intro?courseId=2&agentId=0
边栏推荐
- SAVE: 软件分析验证和测试平台
- Free and easy to use, Tencent arm cloud instance evaluation - AI reasoning acceleration
- Career development planning
- [understanding of opportunity -28]: Guiguzi - Internal Defense chapter - protect yourself and persuade your boss
- MySQL daily experience [02]
- 2022 Shaanxi Provincial Safety Officer C certificate examination question bank simulated examination platform operation
- [cloud picture] episode 244 three minute understanding of container image service
- 2022年危险化学品生产单位主要负责人考试题库及在线模拟考试
- 解决win7任务栏谷歌浏览器chrome图标丢失、异常空白的问题
- Arm load storage instruction
猜你喜欢

Intensive reading: generative adversarial imitation learning

Path Join() and path The difference between resolve()

外贸专题:外贸邮件营销模板

HMS Core新闻行业解决方案:让技术加上人文的温度

线程常用调度方法

QQ email for opencv face recognition
推荐一款M1芯片电脑快速搭建集群的虚拟机软件

rtklib postpos 梳理(以单点定位为例)

本周四晚19:00战码先锋第7期直播丨三方应用开发者如何为开源做贡献

攻防演练 | 基于ATT&CK的威胁狩猎实践案例
随机推荐
Pule frog 5D flying cinema 5D dynamic cinema experience hall equipment 7d multi person interactive cinema
HMS Core新闻行业解决方案:让技术加上人文的温度
2022年深入推进IPv6部署和应用,该如何全面实现安全升级改造?
MySQL lock view
Nodejs basic quick review
嵌入式软件开发之程序架构设计-任务调度
nvm use之后重新打开终端还是显示修改之前的版本
世界上第一个“半机械人”去世,改造自己只为“逆天改命”
Cloud minimalist deployment svelte3 chat room
Customization scheme for DAPP system development mode of smart contract
mysql 锁查看
在 Laravel 中使用计算列
6-13 提高加载性能 - 应用缓存
Should the theme of the IDE be bright or dark? Here comes the ultimate answer!
[JMeter] how JMeter simulates different network speeds
“不敢去怀疑代码,又不得不怀疑代码”记一次网络请求超时分析
SAVE: 软件分析验证和测试平台
将有色液体图像转换成透明液体,CMU教机器人准确掌控向杯中倒多少水
6-9 应用间通信 - 子应用通信
In depth analysis of business model of blind box software development in 2022