SpecialProxy/dns.c

142 lines
3.2 KiB
C
Raw Permalink Normal View History

2017-07-12 12:29:56 +08:00
#include "dns.h"
#include "http.h"
2019-01-26 11:53:32 +08:00
struct dns dns_list[MAX_CONNECTION >> 1]; //一个客户端 + 一个服务端 占用一个dns结构体
2017-07-12 12:29:56 +08:00
int dnsFd;
void read_dns_rsp()
{
2019-01-26 11:53:32 +08:00
static char rsp_data[512], *ip, *p;
2018-10-14 11:58:56 +08:00
struct dns *dns;
conn_t *client;
2019-01-26 11:53:32 +08:00
int16_t len, dns_id;
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
{
2019-01-26 11:53:32 +08:00
memcpy(&dns_id, rsp_data, 2);
dns = dns_list + dns_id;
client = cts + (dns_id << 1);
2017-07-12 12:52:46 +08:00
//判断是否是正常DNS回应是否已关闭连接
2019-01-26 11:53:32 +08:00
if (dns_id > MAX_CONNECTION >> 1 || client->fd < 0)
2017-07-12 12:29:56 +08:00
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;
}
2019-01-26 11:53:32 +08:00
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;
2019-01-26 11:53:32 +08:00
ip = NULL;
2017-07-12 12:29:56 +08:00
while (p - rsp_data + 4 <= len)
{
//type
if (*(p - 8) != 1)
{
p += *p + 12;
continue;
}
2019-01-26 11:53:32 +08:00
ip = p + 1;
2017-07-12 12:29:56 +08:00
break;
}
2019-01-26 11:53:32 +08:00
if (ip == NULL || connectionToServer(*(in_addr_t *)ip, client + 1) != 0)
2017-07-12 12:29:56 +08:00
{
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;
2019-01-26 11:53:32 +08:00
write_len = write(dnsFd, dns->request, dns->request_len);
2017-07-12 12:29:56 +08:00
if (write_len == dns->request_len - dns->sent_len)
{
dns->sent_len = dns->request_len;
return 0;
}
2019-01-26 11:53:32 +08:00
else if (write_len > 0)
2017-07-12 12:29:56 +08:00
{
return 1;
}
else
{
return -1;
}
}
void dns_query()
{
2018-10-14 11:58:56 +08:00
int16_t i, ret;
2019-01-26 11:53:32 +08:00
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;
2019-01-26 11:53:32 +08:00
memcpy(p+1, domain, domain_size + 1);
2017-07-12 12:29:56 +08:00
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:
return 0;
2019-01-26 11:53:32 +08:00
2017-07-12 12:29:56 +08:00
case 1:
ev.data.fd = dnsFd;
ev.events = EPOLLIN|EPOLLOUT|EPOLLET;
epoll_ctl(efd, EPOLL_CTL_MOD, dnsFd, &ev);
return 1;
2019-01-26 11:53:32 +08:00
2017-07-12 12:29:56 +08:00
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);
}