当前位置:网站首页>About UDP receiving ICMP port unreachable
About UDP receiving ICMP port unreachable
2022-04-23 15:04:00 【Mrpre】
This article is divided into 3 part
1: Message format
2: Cause of occurrence
3:linux How the protocol stack handles
4: How to get
1:
The message is as follows ,10.30.13.1 Go to 10.30.16.10 Of 80 The port sent a UDP message ,80 The port actually listens to TCP.
The server replied to an unreachable port ICMP,ICMP The data part is the request UDP ip Layer and above .
2: reason
The first reason is to receive udp The port corresponding to the message server is not opened UDP The server . Notice the description here , It's not that the port is not open , But it didn't open UDP service , If it's on TCP service , Still will return port unreachable.
3:Linux Kernel pair UDP Handle :
(1): As a server, I received a UDP request :
First , As a server , When a message passes through the check route , Purpose ip It's time to deliver this machine , after netfilter After the verdict ,
call ip_local_deliver_finish, It is based on ip Protocol type in header (TCP/UDP/ICMP/......), Call different 4 Layer interface function for processing . So I said before , Even if it's turned on TCP service , Established by the server socket Of hash and udp Super search socket Of hash atypism , It also returns that the port is unreachable .
about udp for ,handler yes udp_rcv, It directly calls __udp4_lib_rcv, Find the corresponding sock,
If sk non-existent if(sk != NULL), Just reply icmp destination unreachable( This means that the server does not have a corresponding port to accept UDP Process flow ), The function is very simple
So as a server , A message that the destination port is not listening is received , The direct reply port is unreachable .
So as a client , How to handle the reply from the server Port unreachable The message ?
At first, the idea was very simple , In my submission , There is no interference between different agreements , namely TCP and UDP There is no direct interference .
Not to mention this nondescript icmp? Then I was wrong .
(2) Received as a client ICMP Port unreachable reply :
As a client , Port unreachable message entry ip_local_deliver_finish, It calls icmp_rcv function , To deal with .( In fact, this is what I thought at the beginning udp There will be no corresponding reason for port unreachable data , because udp The process is udp_rcv).
actually icmp_rcv The most important thing about functions is It calls for :icmp_pointers[icmph->type].handler(skb);
handler = icmp_unreach
icmp_unreach The final step of the function , It's the last step :
Is it very similar ip_local_deliver_finish?
It's very much like , It's just ip_local_deliver_finish in , Called ipprot->handler, And here you call ipprot->err_handler
about udp,err_handler = udp_err = __udp4_lib_err
In this function , Only enter the following process , The application will react :
__udp4_lib_err First, according to skb->data in dip and sip, lookup socket,skb->data yes icmp The load of
So call... First __udp4_lib_lookup lookup socket, Reference time ,sip and dip It needs to be reversed .
__udp4_lib_err:
The prerequisite is inet->recverr For the wrong 0, perhaps inet->recverr by 0 however udp be in TCP_ESTABLISHED state .
Otherwise, the application cannot expect to receive data that is unreachable to the port , The application is waiting read Time out . So , In order to obtain udp Port unreachable condition
Yes 2 Methods :
(1):
int val = 1;
setsockopt(fd, IPPROTO_IP, IP_RECVERR , &val,sizeof(int));
(2):
Yes udp Conduct connect operation , And will sendto Change to send
4:
udp Learn the source program that the port is unreachable ( Method 1: Set up Socket Options ; Method 2: Yes UDP Conduct Connect)
Be careful , In case of congestion ,recvfrom It will block , Even if a port unreachable message is received , It will also block . But after Method 1 and Method 2 after ,recvfrom Returns the , The return value is -1, then Judge errno Whether it is ECONNREFUSED To determine whether the port unreachable message is received .
#include <stdio.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <string.h>
#include <errno.h>
unsigned char revc_buf[1024];
int main()
{
int fd,ret,recv_len,size=1024;
struct sockaddr_in server_addr,addr;
int val = 1;
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = inet_addr("192.168.2.254");
server_addr.sin_port = htons(77);
fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if(fd < 0)
{
perror("socket fail ");
return -1;
}
printf("socket sucess\n");
// Method 1
#if 1
setsockopt(fd, IPPROTO_IP, IP_RECVERR , &val,sizeof(int));
if(sendto(fd, "nihao", strlen("nihao"), 0, (const struct sockaddr *)&(server_addr), sizeof(struct sockaddr_in))<0)
{
perror("sendto fail ");
return -1;
}
printf("sendto sucess\n");
recv_len = recvfrom(fd, revc_buf, sizeof(revc_buf), 0, (struct sockaddr *)&addr, (int *)&size);
if (recv_len == -1)
{
if (errno == ECONNREFUSED)
{
printf("Recv port unreachable\n");
}
}
// Method 2
#elif 0
ret = connect(fd, (const struct sockaddr *) &(server_addr), sizeof (struct sockaddr_in));
if(ret < 0)
{
printf("connect fail\n");
return -1;
}
ret = send(fd, "ni hao", strlen("nihao"),0);
if(ret < 0)
{
printf("write fail\n");
return -1;
}
ret = recvfrom(fd, revc_buf, sizeof(revc_buf), 0, (struct sockaddr *)&addr, (int *)&size);
if (ret == -1) {
if (errno == ECONNREFUSED)
{
printf("Recv port unreachable\n");
}
}
#endif
close(fd);
return 0;
}
If it works for you , One yuan, please :http://www.mrpre.com/
版权声明
本文为[Mrpre]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/04/202204231409587664.html
边栏推荐
- 1 - first knowledge of go language
- 8.2 text preprocessing
- Programming philosophy - automatic loading, dependency injection and control inversion
- MySQL error packet out of order
- Lotus DB design and Implementation - 1 Basic Concepts
- C language super complete learning route (collection allows you to avoid detours)
- Flink DataStream 类型系统 TypeInformation
- LeetCode 练习——396. 旋转函数
- Have you learned the basic operation of circular queue?
- Detailed comparison between asemi three-phase rectifier bridge and single-phase rectifier bridge
猜你喜欢
Detailed explanation of C language knowledge points - data types and variables [2] - integer variables and constants [1]
Share 20 tips for ES6 that should not be missed
分布式事务Seata介绍
8.2 text preprocessing
What is the role of the full connection layer?
Svn detailed use tutorial
Leetcode151 - invert words in string - String - simulation
LeetCode151-颠倒字符串中的单词-字符串-模拟
1 - first knowledge of go language
1-初识Go语言
随机推荐
nuxt项目:全局获取process.env信息
My raspberry PI zero 2W tossing notes record some problems encountered and solutions
Openfaas practice 4: template operation
Leetcode167 - sum of two numbers II - double pointer - bisection - array - Search
Thread synchronization, life cycle
Comment eolink facilite le télétravail
The difference between having and where in SQL
Swift protocol Association object resource name management multithreading GCD delay once
Redis主从同步
牛客网数据库SQL实战详细剖析(26-30)
Alexnet model
Borui data and F5 jointly build the full data chain DNA of financial technology from code to user
Go basic reflection
Vscode Chinese plug-in doesn't work. Problem solving
1-初识Go语言
Thinkphp5 + data large screen display effect
Basic operation of circular queue (Experiment)
win10 任务栏通知区图标不见了
Async void caused the program to crash
We reference My97DatePicker to realize the use of time plug-in