SpecialProxy/dns.c

155 lines
3.6 KiB
C
Raw Normal View History

2017-07-12 12:29:56 +08:00
#include "dns.h"
#include "http.h"
2017-07-12 12:52:46 +08:00
struct dns dns_list[MAX_CONNECTION / 2]; //一个客户端 + 一个服务端 占用一个dns结构体
2017-07-12 12:29:56 +08:00
int dnsFd;
void read_dns_rsp()
{
2018-10-14 11:58:56 +08:00
char rsp_data[512], *p, ip[16];
unsigned char *_p;
struct dns *dns;
conn_t *client;
int16_t len, dns_flag;
2017-07-12 12:29:56 +08:00
2018-10-14 11:58:56 +08:00
while ((len = read(dnsFd, rsp_data, 512)) > 11)
2017-07-12 12:29:56 +08:00
{
memcpy(&dns_flag, rsp_data, 2);
dns = dns_list + dns_flag;
client = cts + (dns_flag << 1);
2017-07-12 12:52:46 +08:00
//判断是否是正常DNS回应是否已关闭连接
2017-07-12 12:29:56 +08:00
if (dns_flag > MAX_CONNECTION >> 1 || client->fd < 0)
continue;
2017-07-12 12:52:46 +08:00
if (dns->request_len + 12 > len || (unsigned char)rsp_data[3] != 128) //char只有7位可用则正数最高为127
2017-07-12 12:29:56 +08:00
{
close_connection(client);
continue;
}
2018-10-14 11:58:56 +08:00
/* get domain ip */
2017-07-12 12:29:56 +08:00
p = rsp_data + dns->request_len + 11;
2018-10-14 11:58:56 +08:00
ip[0] = 0;
2017-07-12 12:29:56 +08:00
while (p - rsp_data + 4 <= len)
{
//type
if (*(p - 8) != 1)
{
p += *p + 12;
continue;
}
_p = (unsigned char *)p + 1;
2018-10-14 11:58:56 +08:00
sprintf(ip, "%d.%d.%d.%d", _p[0], _p[1], _p[2], _p[3]);
2017-07-12 12:29:56 +08:00
break;
}
2018-10-14 11:58:56 +08:00
if (ip[0])
2017-07-12 12:29:56 +08:00
{
2018-10-14 11:58:56 +08:00
if (connectionToServer(ip, client + 1) != 0)
2017-07-12 12:29:56 +08:00
{
close_connection(client);
continue;
}
}
else
{
close_connection(client);
continue;
}
}
}
2017-07-12 12:52:46 +08:00
/* 完全发送返回0发送部分返回1出错返回-1 */
2017-07-12 12:29:56 +08:00
static int8_t send_dns_req(struct dns *dns)
{
2018-10-14 11:58:56 +08:00
int write_len;
2017-07-12 12:29:56 +08:00
write_len = write(dnsFd, dns->request + dns->sent_len, dns->request_len - dns->sent_len);
if (write_len == dns->request_len - dns->sent_len)
{
dns->sent_len = dns->request_len;
return 0;
}
else if (write_len >= 0)
{
dns->sent_len += write_len;
return 1;
}
else
{
return -1;
}
}
void dns_query()
{
2018-10-14 11:58:56 +08:00
int16_t i, ret;
2017-07-12 12:29:56 +08:00
for (i = 0; i < MAX_CONNECTION >> 1; i++)
{
if (dns_list[i].request_len != dns_list[i].sent_len)
{
ret = send_dns_req(dns_list + i);
if (ret == 1)
break;
else if (ret == -1)
close_connection(cts + (i << 1));
}
}
2018-10-14 11:58:56 +08:00
//dnsFd的缓冲区以满
if (i < MAX_CONNECTION >> 1)
{
2017-07-12 12:29:56 +08:00
ev.events = EPOLLIN|EPOLLOUT|EPOLLET;
2018-10-14 11:58:56 +08:00
ev.data.fd = dnsFd;
epoll_ctl(efd, EPOLL_CTL_MOD, dnsFd, &ev);
}
2017-07-12 12:29:56 +08:00
}
int8_t build_dns_req(struct dns *dns, char *domain)
{
2018-10-14 11:58:56 +08:00
char *p, *_p;
int8_t domain_size;
2017-07-12 12:29:56 +08:00
domain_size = strlen(domain);
p = dns->request + 12;
memcpy(p+1, domain, domain_size);
*(p+1+domain_size) = 0;
while ((_p = strchr(p+1, '.')) != NULL)
{
*p = _p - p - 1;
p = _p;
}
*p = strlen(p+1);
p = dns->request + 14 + domain_size;
*p++ = 0;
*p++ = 1;
*p++ = 0;
*p++ = 1;
dns->request_len = p - dns->request;
switch (send_dns_req(dns))
{
case 0:
ev.data.fd = dnsFd;
return 0;
case 1:
ev.data.fd = dnsFd;
ev.events = EPOLLIN|EPOLLOUT|EPOLLET;
epoll_ctl(efd, EPOLL_CTL_MOD, dnsFd, &ev);
return 1;
default:
return -1;
}
}
void dns_connect(struct sockaddr_in *dnsAddr)
{
2017-07-12 12:52:46 +08:00
dnsFd = socket(AF_INET, SOCK_DGRAM, 0);
2017-07-12 12:29:56 +08:00
if (dnsFd < 0)
{
perror("socket");
exit(1);
}
2017-07-12 12:52:46 +08:00
connect(dnsFd, (struct sockaddr *)dnsAddr, sizeof(struct sockaddr_in));
2017-07-12 12:29:56 +08:00
fcntl(dnsFd, F_SETFL, O_NONBLOCK);
}