Support DNS Over HTTPS
This commit is contained in:
290
src/dns_client.c
290
src/dns_client.c
@@ -22,6 +22,7 @@
|
||||
#include "dns_conf.h"
|
||||
#include "fast_ping.h"
|
||||
#include "hashtable.h"
|
||||
#include "http_parse.h"
|
||||
#include "list.h"
|
||||
#include "tlog.h"
|
||||
#include "util.h"
|
||||
@@ -96,9 +97,6 @@ struct dns_server_info {
|
||||
/* server type */
|
||||
dns_server_type_t type;
|
||||
|
||||
unsigned char *spki;
|
||||
int spki_len;
|
||||
|
||||
/* client socket */
|
||||
int fd;
|
||||
int ttl;
|
||||
@@ -107,7 +105,6 @@ struct dns_server_info {
|
||||
SSL_CTX *ssl_ctx;
|
||||
SSL_SESSION *ssl_session;
|
||||
dns_server_status status;
|
||||
unsigned int result_flag;
|
||||
|
||||
struct dns_server_buff send_buff;
|
||||
struct dns_server_buff recv_buff;
|
||||
@@ -124,6 +121,8 @@ struct dns_server_info {
|
||||
struct sockaddr_in6 in6;
|
||||
struct sockaddr addr;
|
||||
};
|
||||
|
||||
struct client_dns_server_flags flags;
|
||||
};
|
||||
|
||||
/* upstream server group member */
|
||||
@@ -298,8 +297,9 @@ static struct dns_server_info *_dns_client_get_server(char *server_ip, int port,
|
||||
case DNS_SERVER_UDP:
|
||||
sock_type = SOCK_DGRAM;
|
||||
break;
|
||||
case DNS_SERVER_TLS:
|
||||
case DNS_SERVER_TCP:
|
||||
case DNS_SERVER_TLS:
|
||||
case DNS_SERVER_HTTPS:
|
||||
sock_type = SOCK_STREAM;
|
||||
break;
|
||||
default:
|
||||
@@ -572,26 +572,88 @@ static void _dns_client_group_remove_all(void)
|
||||
}
|
||||
}
|
||||
|
||||
int dns_client_spki_decode(const char *spki, unsigned char *spki_data_out)
|
||||
{
|
||||
int spki_data_len = -1;
|
||||
|
||||
spki_data_len = SSL_base64_decode(spki, spki_data_out);
|
||||
|
||||
if (spki_data_len != SHA256_DIGEST_LENGTH) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return spki_data_len;
|
||||
}
|
||||
|
||||
static char *_dns_client_server_get_spki(struct dns_server_info *server_info, int *spki_len)
|
||||
{
|
||||
*spki_len = 0;
|
||||
char *spki = NULL;
|
||||
switch (server_info->type) {
|
||||
case DNS_SERVER_UDP: {
|
||||
} break;
|
||||
case DNS_SERVER_HTTPS: {
|
||||
struct client_dns_server_flag_https *flag_https = &server_info->flags.https;
|
||||
spki = flag_https->spki;
|
||||
*spki_len = flag_https->spi_len;
|
||||
} break;
|
||||
case DNS_SERVER_TLS: {
|
||||
struct client_dns_server_flag_tls *flag_tls = &server_info->flags.tls;
|
||||
spki = flag_tls->spki;
|
||||
*spki_len = flag_tls->spi_len;
|
||||
} break;
|
||||
break;
|
||||
case DNS_SERVER_TCP:
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (*spki_len <= 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return spki;
|
||||
}
|
||||
|
||||
/* add dns server information */
|
||||
static int _dns_client_server_add(char *server_ip, struct addrinfo *gai, dns_server_type_t server_type, unsigned int server_flag, unsigned int result_flag,
|
||||
int ttl, char *spki)
|
||||
static int _dns_client_server_add(char *server_ip, struct addrinfo *gai, dns_server_type_t server_type, struct client_dns_server_flags *flags)
|
||||
{
|
||||
struct dns_server_info *server_info = NULL;
|
||||
unsigned char *spki_data = NULL;
|
||||
int spki_data_len = 0;
|
||||
int ttl = 0;
|
||||
|
||||
/* read SPKI value, base64 sha256 value */
|
||||
if (spki && (strlen(spki) < DNS_MAX_SPKI_LEN)) {
|
||||
spki_data = malloc(DNS_MAX_SPKI_LEN);
|
||||
if (spki_data) {
|
||||
memset(spki_data, 0, DNS_MAX_SPKI_LEN);
|
||||
spki_data_len = SSL_base64_decode(spki, spki_data);
|
||||
if (spki_data_len != SHA256_DIGEST_LENGTH) {
|
||||
free(spki_data);
|
||||
spki_data = NULL;
|
||||
spki_data_len = 0;
|
||||
}
|
||||
switch (server_type) {
|
||||
case DNS_SERVER_UDP: {
|
||||
struct client_dns_server_flag_udp *flag_udp = &flags->udp;
|
||||
ttl = flag_udp->ttl;
|
||||
if (ttl > 255) {
|
||||
ttl = 255;
|
||||
} else if (ttl < -32) {
|
||||
ttl = -32;
|
||||
}
|
||||
} break;
|
||||
case DNS_SERVER_HTTPS: {
|
||||
struct client_dns_server_flag_https *flag_https = &flags->https;
|
||||
spki_data_len = flag_https->spi_len;
|
||||
} break;
|
||||
case DNS_SERVER_TLS: {
|
||||
struct client_dns_server_flag_tls *flag_tls = &flags->tls;
|
||||
spki_data_len = flag_tls->spi_len;
|
||||
} break;
|
||||
break;
|
||||
case DNS_SERVER_TCP:
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (spki_data_len > DNS_SERVER_SPKI_LEN) {
|
||||
tlog(TLOG_ERROR, "spki data length is invalid.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* if server exist, return */
|
||||
@@ -605,7 +667,7 @@ static int _dns_client_server_add(char *server_ip, struct addrinfo *gai, dns_ser
|
||||
}
|
||||
|
||||
if (server_type != DNS_SERVER_UDP) {
|
||||
result_flag &= (~DNSSERVER_FLAG_CHECK_TTL);
|
||||
flags->result_flag &= (~DNSSERVER_FLAG_CHECK_TTL);
|
||||
}
|
||||
|
||||
memset(server_info, 0, sizeof(*server_info));
|
||||
@@ -615,14 +677,12 @@ static int _dns_client_server_add(char *server_ip, struct addrinfo *gai, dns_ser
|
||||
server_info->type = server_type;
|
||||
server_info->fd = 0;
|
||||
server_info->status = DNS_SERVER_STATUS_INIT;
|
||||
server_info->result_flag = result_flag;
|
||||
server_info->ttl = ttl;
|
||||
server_info->ttl_range = 0;
|
||||
server_info->spki = spki_data;
|
||||
server_info->spki_len = spki_data_len;
|
||||
memcpy(&server_info->flags, flags, sizeof(server_info->flags));
|
||||
|
||||
/* exclude this server from default group */
|
||||
if ((server_flag & SERVER_FLAG_EXCLUDE_DEFAULT) == 0) {
|
||||
if ((server_info->flags.server_flag & SERVER_FLAG_EXCLUDE_DEFAULT) == 0) {
|
||||
if (_dns_client_add_to_group(DNS_SERVER_GROUP_DEFAULT, server_info) != 0) {
|
||||
tlog(TLOG_ERROR, "add server to default group failed.");
|
||||
goto errout;
|
||||
@@ -630,7 +690,7 @@ static int _dns_client_server_add(char *server_ip, struct addrinfo *gai, dns_ser
|
||||
}
|
||||
|
||||
/* if server type is TLS, create ssl context */
|
||||
if (server_type == DNS_SERVER_TLS) {
|
||||
if (server_type == DNS_SERVER_TLS || server_type == DNS_SERVER_HTTPS) {
|
||||
server_info->ssl_ctx = SSL_CTX_new(SSLv23_client_method());
|
||||
if (server_info->ssl_ctx == NULL) {
|
||||
tlog(TLOG_ERROR, "init ssl failed.");
|
||||
@@ -646,15 +706,17 @@ static int _dns_client_server_add(char *server_ip, struct addrinfo *gai, dns_ser
|
||||
memcpy(&server_info->addr, gai->ai_addr, gai->ai_addrlen);
|
||||
|
||||
/* start ping task */
|
||||
if (ttl <= 0 && (result_flag & DNSSERVER_FLAG_CHECK_TTL)) {
|
||||
server_info->ping_host = fast_ping_start(PING_TYPE_DNS, server_ip, 0, 60000, 1000, _dns_client_server_update_ttl, server_info);
|
||||
if (server_info->ping_host == NULL) {
|
||||
tlog(TLOG_ERROR, "start ping failed.");
|
||||
goto errout;
|
||||
}
|
||||
if (server_type == DNS_SERVER_UDP) {
|
||||
if (ttl <= 0 && (server_info->flags.result_flag & DNSSERVER_FLAG_CHECK_TTL)) {
|
||||
server_info->ping_host = fast_ping_start(PING_TYPE_DNS, server_ip, 0, 60000, 1000, _dns_client_server_update_ttl, server_info);
|
||||
if (server_info->ping_host == NULL) {
|
||||
tlog(TLOG_ERROR, "start ping failed.");
|
||||
goto errout;
|
||||
}
|
||||
|
||||
if (ttl < 0) {
|
||||
server_info->ttl_range = -ttl;
|
||||
if (ttl < 0) {
|
||||
server_info->ttl_range = -ttl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -741,10 +803,6 @@ static void _dns_client_server_remove_all(void)
|
||||
{
|
||||
list_del(&server_info->list);
|
||||
_dns_client_server_close(server_info);
|
||||
if (server_info->spki) {
|
||||
free(server_info->spki);
|
||||
server_info->spki = NULL;
|
||||
}
|
||||
free(server_info);
|
||||
}
|
||||
pthread_mutex_unlock(&client.server_list_lock);
|
||||
@@ -779,8 +837,7 @@ static int _dns_client_server_remove(char *server_ip, struct addrinfo *gai, dns_
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int _dns_client_server_operate(char *server_ip, int port, dns_server_type_t server_type, unsigned int server_flag, unsigned int result_flag, int ttl,
|
||||
char *spki, int operate)
|
||||
static int _dns_client_server_operate(char *server_ip, int port, dns_server_type_t server_type, struct client_dns_server_flags *flags, int operate)
|
||||
{
|
||||
char port_s[8];
|
||||
int sock_type;
|
||||
@@ -796,8 +853,9 @@ static int _dns_client_server_operate(char *server_ip, int port, dns_server_type
|
||||
case DNS_SERVER_UDP:
|
||||
sock_type = SOCK_DGRAM;
|
||||
break;
|
||||
case DNS_SERVER_TLS:
|
||||
case DNS_SERVER_TCP:
|
||||
case DNS_SERVER_TLS:
|
||||
case DNS_SERVER_HTTPS:
|
||||
sock_type = SOCK_STREAM;
|
||||
break;
|
||||
default:
|
||||
@@ -815,7 +873,7 @@ static int _dns_client_server_operate(char *server_ip, int port, dns_server_type
|
||||
|
||||
if (operate == 0) {
|
||||
/* add server */
|
||||
ret = _dns_client_server_add(server_ip, gai, server_type, server_flag, result_flag, ttl, spki);
|
||||
ret = _dns_client_server_add(server_ip, gai, server_type, flags);
|
||||
if (ret != 0) {
|
||||
goto errout;
|
||||
}
|
||||
@@ -835,14 +893,14 @@ errout:
|
||||
return -1;
|
||||
}
|
||||
|
||||
int dns_client_add_server(char *server_ip, int port, dns_server_type_t server_type, unsigned server_flag, unsigned int result_flag, int ttl, char *spki)
|
||||
int dns_client_add_server(char *server_ip, int port, dns_server_type_t server_type, struct client_dns_server_flags *flags)
|
||||
{
|
||||
return _dns_client_server_operate(server_ip, port, server_type, server_flag, result_flag, ttl, spki, 0);
|
||||
return _dns_client_server_operate(server_ip, port, server_type, flags, 0);
|
||||
}
|
||||
|
||||
int dns_client_remove_server(char *server_ip, int port, dns_server_type_t server_type)
|
||||
{
|
||||
return _dns_client_server_operate(server_ip, port, server_type, 0, 0, 0, NULL, 1);
|
||||
return _dns_client_server_operate(server_ip, port, server_type, NULL, 1);
|
||||
}
|
||||
|
||||
int dns_server_num(void)
|
||||
@@ -1101,7 +1159,7 @@ static int _dns_client_recv(struct dns_server_info *server_info, unsigned char *
|
||||
|
||||
/* get query reference */
|
||||
query = _dns_client_get_request(packet->head.id, domain);
|
||||
if (query == NULL || (query && has_opt == 0 && server_info->result_flag & DNSSERVER_FLAG_CHECK_EDNS)) {
|
||||
if (query == NULL || (query && has_opt == 0 && server_info->flags.result_flag & DNSSERVER_FLAG_CHECK_EDNS)) {
|
||||
if (query) {
|
||||
_dns_client_query_release(query);
|
||||
}
|
||||
@@ -1123,7 +1181,7 @@ static int _dns_client_recv(struct dns_server_info *server_info, unsigned char *
|
||||
|
||||
/* notify caller dns query result */
|
||||
if (query->callback) {
|
||||
ret = query->callback(query->domain, DNS_QUERY_RESULT, server_info->result_flag, packet, inpacket, inpacket_len, query->user_ptr);
|
||||
ret = query->callback(query->domain, DNS_QUERY_RESULT, server_info->flags.result_flag, packet, inpacket, inpacket_len, query->user_ptr);
|
||||
if (request_num == 0 || ret) {
|
||||
/* if all server replied, or done, stop query, release resource */
|
||||
_dns_client_query_remove(query);
|
||||
@@ -1326,7 +1384,7 @@ static int _dns_client_create_socket(struct dns_server_info *server_info)
|
||||
return _dns_client_create_socket_udp(server_info);
|
||||
} else if (server_info->type == DNS_SERVER_TCP) {
|
||||
return _DNS_client_create_socket_tcp(server_info);
|
||||
} else if (server_info->type == DNS_SERVER_TLS) {
|
||||
} else if (server_info->type == DNS_SERVER_TLS || server_info->type == DNS_SERVER_HTTPS) {
|
||||
return _DNS_client_create_socket_tls(server_info);
|
||||
} else {
|
||||
return -1;
|
||||
@@ -1382,7 +1440,7 @@ static int _dns_client_process_udp(struct dns_server_info *server_info, struct e
|
||||
|
||||
tlog(TLOG_DEBUG, "recv udp packet from %s, len: %d, ttl: %d", gethost_by_addr(from_host, sizeof(from_host), (struct sockaddr *)&from), len, ttl);
|
||||
|
||||
if ((ttl != server_info->ttl) && (server_info->ttl > 0) && (server_info->result_flag & DNSSERVER_FLAG_CHECK_TTL)) {
|
||||
if ((ttl != server_info->ttl) && (server_info->ttl > 0) && (server_info->flags.result_flag & DNSSERVER_FLAG_CHECK_TTL)) {
|
||||
/* If TTL check is enabled but the TTL is inconsistent, it is considered to be a fake dns packet */
|
||||
if ((ttl < server_info->ttl - server_info->ttl_range) || (ttl > server_info->ttl + server_info->ttl_range)) {
|
||||
/* tlog(TLOG_DEBUG, "TTL mismatch, from:%d, local %d, discard result", ttl, server_info->ttl); */
|
||||
@@ -1521,7 +1579,7 @@ static int _dns_client_socket_send(struct dns_server_info *server_info)
|
||||
return -1;
|
||||
} else if (server_info->type == DNS_SERVER_TCP) {
|
||||
return send(server_info->fd, server_info->send_buff.data, server_info->send_buff.len, MSG_NOSIGNAL);
|
||||
} else if (server_info->type == DNS_SERVER_TLS) {
|
||||
} else if (server_info->type == DNS_SERVER_TLS || server_info->type == DNS_SERVER_HTTPS) {
|
||||
return _dns_client_socket_ssl_send(server_info->ssl, server_info->send_buff.data, server_info->send_buff.len);
|
||||
} else {
|
||||
return -1;
|
||||
@@ -1534,7 +1592,7 @@ static int _dns_client_socket_recv(struct dns_server_info *server_info)
|
||||
return -1;
|
||||
} else if (server_info->type == DNS_SERVER_TCP) {
|
||||
return recv(server_info->fd, server_info->recv_buff.data + server_info->recv_buff.len, DNS_TCP_BUFFER - server_info->recv_buff.len, 0);
|
||||
} else if (server_info->type == DNS_SERVER_TLS) {
|
||||
} else if (server_info->type == DNS_SERVER_TLS || server_info->type == DNS_SERVER_HTTPS) {
|
||||
return _dns_client_socket_ssl_recv(server_info->ssl, server_info->recv_buff.data + server_info->recv_buff.len,
|
||||
DNS_TCP_BUFFER - server_info->recv_buff.len);
|
||||
} else {
|
||||
@@ -1545,7 +1603,9 @@ static int _dns_client_socket_recv(struct dns_server_info *server_info)
|
||||
static int _dns_client_process_tcp(struct dns_server_info *server_info, struct epoll_event *event, unsigned long now)
|
||||
{
|
||||
int len;
|
||||
int dns_packet_len = 0;
|
||||
int ret = -1;
|
||||
struct http_head *http_head = NULL;
|
||||
unsigned char *inpacket_data = NULL;
|
||||
|
||||
if (event->events & EPOLLIN) {
|
||||
@@ -1591,29 +1651,61 @@ static int _dns_client_process_tcp(struct dns_server_info *server_info, struct e
|
||||
}
|
||||
|
||||
while (1) {
|
||||
/* tcp result format
|
||||
* | len (short) | dns query result |
|
||||
*/
|
||||
inpacket_data = server_info->recv_buff.data;
|
||||
len = ntohs(*((unsigned short *)(inpacket_data)));
|
||||
if (len <= 0 || len >= DNS_IN_PACKSIZE) {
|
||||
/* data len is invalid */
|
||||
goto errout;
|
||||
}
|
||||
if (server_info->type == DNS_SERVER_HTTPS) {
|
||||
http_head = http_head_init(4096);
|
||||
if (http_head == NULL) {
|
||||
goto errout;
|
||||
}
|
||||
|
||||
if (len > server_info->recv_buff.len - 2) {
|
||||
/* len is not expceded, wait and recv */
|
||||
break;
|
||||
}
|
||||
len = http_head_parse(http_head, (char *)server_info->recv_buff.data, server_info->recv_buff.len);
|
||||
if (len < 0) {
|
||||
http_head_destroy(http_head);
|
||||
if (len == -1) {
|
||||
break;
|
||||
}
|
||||
goto errout;
|
||||
}
|
||||
|
||||
inpacket_data = server_info->recv_buff.data + 2;
|
||||
if (http_head_get_httpcode(http_head) != 200) {
|
||||
tlog(TLOG_WARN, "http server query failed, server return http code : %d, %s", http_head_get_httpcode(http_head),
|
||||
http_head_get_httpcode_msg(http_head));
|
||||
goto errout;
|
||||
}
|
||||
|
||||
dns_packet_len = http_head_get_data_len(http_head);
|
||||
inpacket_data = (unsigned char *)http_head_get_data(http_head);
|
||||
} else {
|
||||
/* tcp result format
|
||||
* | len (short) | dns query result |
|
||||
*/
|
||||
inpacket_data = server_info->recv_buff.data;
|
||||
len = ntohs(*((unsigned short *)(inpacket_data)));
|
||||
if (len <= 0 || len >= DNS_IN_PACKSIZE) {
|
||||
/* data len is invalid */
|
||||
goto errout;
|
||||
}
|
||||
|
||||
if (len > server_info->recv_buff.len - 2) {
|
||||
/* len is not expceded, wait and recv */
|
||||
break;
|
||||
}
|
||||
|
||||
inpacket_data = server_info->recv_buff.data + 2;
|
||||
dns_packet_len = len;
|
||||
len += 2;
|
||||
}
|
||||
tlog(TLOG_DEBUG, "recv tcp packet from %s, len = %d", server_info->ip, len);
|
||||
|
||||
/* process result */
|
||||
if (_dns_client_recv(server_info, inpacket_data, len, &server_info->addr, server_info->ai_addrlen) != 0) {
|
||||
if (_dns_client_recv(server_info, inpacket_data, dns_packet_len, &server_info->addr, server_info->ai_addrlen) != 0) {
|
||||
goto errout;
|
||||
}
|
||||
len += 2;
|
||||
|
||||
if (http_head) {
|
||||
http_head_destroy(http_head);
|
||||
http_head = NULL;
|
||||
}
|
||||
|
||||
server_info->recv_buff.len -= len;
|
||||
|
||||
/* move to next result */
|
||||
@@ -1677,6 +1769,10 @@ static int _dns_client_process_tcp(struct dns_server_info *server_info, struct e
|
||||
return 0;
|
||||
|
||||
errout:
|
||||
if (http_head) {
|
||||
http_head_destroy(http_head);
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&client.server_list_lock);
|
||||
server_info->recv_buff.len = 0;
|
||||
server_info->send_buff.len = 0;
|
||||
@@ -1705,6 +1801,8 @@ static int _dns_client_tls_verify(struct dns_server_info *server_info)
|
||||
unsigned char *key_data = NULL;
|
||||
unsigned char *key_data_tmp = NULL;
|
||||
unsigned char *key_sha256 = NULL;
|
||||
char *spki = NULL;
|
||||
int spki_len = 0;
|
||||
|
||||
cert = SSL_get_peer_certificate(server_info->ssl);
|
||||
if (cert == NULL) {
|
||||
@@ -1751,9 +1849,10 @@ static int _dns_client_tls_verify(struct dns_server_info *server_info)
|
||||
*ptr = 0;
|
||||
tlog(TLOG_DEBUG, "cert SPKI pin(%s): %s", "sha256", cert_fingerprint);
|
||||
|
||||
if (server_info->spki) {
|
||||
spki = _dns_client_server_get_spki(server_info, &spki_len);
|
||||
if (spki) {
|
||||
/* check SPKI */
|
||||
if (memcmp(server_info->spki, key_sha256, server_info->spki_len) != 0) {
|
||||
if (memcmp(spki, key_sha256, spki_len) != 0) {
|
||||
tlog(TLOG_INFO, "server %s cert spki is invalid", server_info->ip);
|
||||
goto errout;
|
||||
} else {
|
||||
@@ -1858,7 +1957,7 @@ static int _dns_client_process(struct dns_server_info *server_info, struct epoll
|
||||
} else if (server_info->type == DNS_SERVER_TCP) {
|
||||
/* receive from tcp */
|
||||
return _dns_client_process_tcp(server_info, event, now);
|
||||
} else if (server_info->type == DNS_SERVER_TLS) {
|
||||
} else if (server_info->type == DNS_SERVER_TLS || server_info->type == DNS_SERVER_HTTPS) {
|
||||
/* recive from tls */
|
||||
return _dns_client_process_tls(server_info, event, now);
|
||||
} else {
|
||||
@@ -1992,6 +2091,56 @@ static int _dns_client_send_tls(struct dns_server_info *server_info, void *packe
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _dns_client_send_https(struct dns_server_info *server_info, void *packet, unsigned short len)
|
||||
{
|
||||
int send_len = 0;
|
||||
int http_len = 0;
|
||||
unsigned char inpacket_data[DNS_IN_PACKSIZE];
|
||||
unsigned char *inpacket = inpacket_data;
|
||||
struct client_dns_server_flag_https *https_flag = NULL;
|
||||
|
||||
if (len > sizeof(inpacket_data) - 2) {
|
||||
tlog(TLOG_ERROR, "packet size is invalid.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
https_flag = &server_info->flags.https;
|
||||
|
||||
http_len = snprintf((char *)inpacket, DNS_IN_PACKSIZE,
|
||||
"POST %s HTTP/1.1\r\n"
|
||||
"Host: %s\r\n"
|
||||
"content-type: application/dns-message\r\n"
|
||||
"Content-Length: %d\r\n"
|
||||
"\r\n",
|
||||
https_flag->path, https_flag->host, len);
|
||||
memcpy(inpacket + http_len, packet, len);
|
||||
http_len += len;
|
||||
|
||||
if (server_info->status != DNS_SERVER_STATUS_CONNECTED) {
|
||||
return _dns_client_send_data_to_buffer(server_info, inpacket, http_len);
|
||||
}
|
||||
|
||||
if (server_info->ssl == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
send_len = _dns_client_socket_ssl_send(server_info->ssl, inpacket, http_len);
|
||||
if (send_len < 0) {
|
||||
if (errno == EAGAIN || server_info->ssl == NULL) {
|
||||
/* save data to buffer, and retry when EPOLLOUT is available */
|
||||
return _dns_client_send_data_to_buffer(server_info, inpacket, http_len);
|
||||
} else if (server_info->ssl && errno != ENOMEM) {
|
||||
SSL_shutdown(server_info->ssl);
|
||||
}
|
||||
return -1;
|
||||
} else if (send_len < http_len) {
|
||||
/* save remain data to buffer, and retry when EPOLLOUT is available */
|
||||
return _dns_client_send_data_to_buffer(server_info, inpacket + send_len, http_len - send_len);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _dns_client_send_packet(struct dns_query_struct *query, void *packet, int len)
|
||||
{
|
||||
struct dns_server_info *server_info = NULL;
|
||||
@@ -2031,6 +2180,11 @@ static int _dns_client_send_packet(struct dns_query_struct *query, void *packet,
|
||||
ret = _dns_client_send_tls(server_info, packet, len);
|
||||
send_err = errno;
|
||||
break;
|
||||
case DNS_SERVER_HTTPS:
|
||||
/* https query */
|
||||
ret = _dns_client_send_https(server_info, packet, len);
|
||||
send_err = errno;
|
||||
break;
|
||||
default:
|
||||
/* unsupport query type */
|
||||
ret = -1;
|
||||
|
||||
Reference in New Issue
Block a user