当前位置:网站首页>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
边栏推荐
- go基础 反射
- 2-GO variable operation
- [proteus simulation] automatic range (range < 10V) switching digital voltmeter
- Tencent has written a few words, Ali has written them all for a month
- Five data types of redis
- 1990年1月1日是星期一,定义函数date_to_week(year,month,day),实现功能输入年月日后返回星期几,例如date_to_week(2020,11,1),返回:星期日。 提示:
- Borui data and F5 jointly build the full data chain DNA of financial technology from code to user
- How to design a good API interface?
- 冰冰学习笔记:一步一步带你实现顺序表
- The win10 taskbar notification area icon is missing
猜你喜欢
eolink 如何助力遠程辦公
we引用My97DatePicker 实现时间插件使用
Swift - literal, literal protocol, conversion between basic data types and dictionary / array
[untitled]
Basic operation of circular queue (Experiment)
8.2 text preprocessing
1n5408-asemi rectifier diode
QT Detailed explanation of pro file
Swift protocol Association object resource name management multithreading GCD delay once
8.4 realization of recurrent neural network from zero
随机推荐
Fill in the next right node pointer II of each node [classical hierarchy traversal | regarded as linked list]
[untitled]
Llvm - generate local variables
编程哲学——自动加载、依赖注入与控制反转
Design of digital temperature monitoring and alarm system based on DS18B20 single chip microcomputer [LCD1602 display + Proteus simulation + C program + paper + key setting, etc.]
Share 20 tips for ES6 that should not be missed
Daily question - leetcode396 - rotation function - recursion
Leetcode exercise - 396 Rotation function
Set up an AI team in the game world and start the super parametric multi-agent "chaos fight"
Go basic reflection
A series of problems about the best time to buy and sell stocks
Epoll's et, lt working mode -- example program
Thinkphp5 + data large screen display effect
Alexnet model
Sqlserver transaction and lock problem
Programming philosophy - automatic loading, dependency injection and control inversion
PSYNC synchronization of redis source code analysis
async void 导致程序崩溃
小红书 timestamp2 (2022/04/22)
Advanced application of I / O multiplexing: Processing TCP and UDP services at the same time