当前位置:网站首页>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
边栏推荐
- 3、 Gradient descent solution θ
- 帧同步 实现
- Vous ne connaissez pas encore les scénarios d'utilisation du modèle de chaîne de responsabilité?
- Unity_ Code mode add binding button click event
- JS - implémenter la fonction de copie par clic
- PSYNC synchronization of redis source code analysis
- For 22 years, you didn't know the file contained vulnerabilities?
- Difference between like and regexp
- On the day of entry, I cried (mushroom street was laid off and fought for seven months to win the offer)
- 我的 Raspberry Pi Zero 2W 折腾笔记,记录一些遇到的问题和解决办法
猜你喜欢

My raspberry PI zero 2W tossing notes record some problems encountered and solutions

LeetCode165-比较版本号-双指针-字符串

每日一题-LeetCode396-旋转函数-递推

we引用My97DatePicker 实现时间插件使用

你还不知道责任链模式的使用场景吗?

Redis master-slave synchronization

Bingbing learning notes: take you step by step to realize the sequence table

8.3 language model and data set

3、 Gradient descent solution θ

Detailed comparison between asemi three-phase rectifier bridge and single-phase rectifier bridge
随机推荐
OPPO数据湖统一存储技术实践
如何打开Win10启动文件夹?
Resolve the conflict between computed attribute and input blur event
Sqlserver transaction and lock problem
Detailed comparison between asemi three-phase rectifier bridge and single-phase rectifier bridge
Comment eolink facilite le télétravail
How to write the keywords in the cover and title? As we media, why is there no video playback
Mds55-16-asemi rectifier module mds55-16
How do I open the win10 startup folder?
Introduction to dirty reading, unrepeatable reading and phantom reading
How to use OCR in 5 minutes
What is the main purpose of PCIe X1 slot?
Difference between like and regexp
Alexnet model
One of the advanced applications of I / O reuse: non blocking connect -- implemented using select (or poll)
Leetcode151 - invert words in string - String - simulation
I/O复用的高级应用:同时处理 TCP 和 UDP 服务
LeetCode153-寻找旋转排序数组中的最小值-数组-二分查找
8.5 concise implementation of cyclic neural network
I/O复用的高级应用之一:非阻塞 connect———使用 select 实现(也可以用 poll 实现)