当前位置:网站首页>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
边栏推荐
- Thinkphp5 + data large screen display effect
- How do I open the win10 startup folder?
- Don't you know the usage scenario of the responsibility chain model?
- LeetCode149-直线上最多的点数-数学-哈希表
- Practice of unified storage technology of oppo data Lake
- My raspberry PI zero 2W tossing notes record some problems encountered and solutions
- Swift: entry of program, swift calls OC@_ silgen_ Name, OC calls swift, dynamic, string, substring
- 1-初识Go语言
- Three uses of kprobe
- OC to swift conditional compilation, marking, macro, log, version detection, expiration prompt
猜你喜欢
Leetcode162 - find peak - dichotomy - array
Leetcode151 - invert words in string - String - simulation
What is the main purpose of PCIe X1 slot?
My raspberry PI zero 2W tossing notes record some problems encountered and solutions
分布式事务Seata介绍
MySQL error packet out of order
LeetCode151-颠倒字符串中的单词-字符串-模拟
Introduction to Arduino for esp8266 serial port function
大文件如何快速上传?
[stc8g2k64s4] introduction of comparator and sample program of comparator power down detection
随机推荐
Async keyword
Do (local scope), initializer, memory conflict, swift pointer, inout, unsafepointer, unsafebitcast, success
C语言超全学习路线(收藏让你少走弯路)
Five data types of redis
Thinkphp5 + data large screen display effect
3、 Gradient descent solution θ
Progress in the treatment of depression
Llvm - generate local variables
Fill in the next right node pointer II of each node [classical hierarchy traversal | regarded as linked list]
如何打开Win10启动文件夹?
Mds55-16-asemi rectifier module mds55-16
Set up an AI team in the game world and start the super parametric multi-agent "chaos fight"
LeetCode 练习——396. 旋转函数
Unity_ Code mode add binding button click event
Contraction mapping theorem
Don't you know the usage scenario of the responsibility chain model?
Introduction to Arduino for esp8266 serial port function
Vscode Chinese plug-in doesn't work. Problem solving
分享3个使用工具,在家剪辑5个作品挣了400多
Explanation and example application of the principle of logistic regression in machine learning