diff --git a/package/luci/files/luci/i18n/smartdns.zh-cn.po b/package/luci/files/luci/i18n/smartdns.zh-cn.po index 0ba7246..8eb49ac 100644 --- a/package/luci/files/luci/i18n/smartdns.zh-cn.po +++ b/package/luci/files/luci/i18n/smartdns.zh-cn.po @@ -139,6 +139,18 @@ msgstr "协议类型" msgid "Domain Address" msgstr "域名地址" +msgid "TLS SNI name" +msgstr "TLS SNI名称" + +msgid "HTTP Host" +msgstr "HTTP主机" + +msgid "Sets the server name indication" +msgstr "设置服务器SNI名称" + +msgid "Set the HTTP host used for the query. Use this parameter when the host of the URL address is an IP address." +msgstr "设置查询时使用的HTTP主机,当URL地址的host是IP地址时,使用此参数。" + msgid "Server Group" msgstr "服务器组" diff --git a/package/luci/files/luci/model/cbi/smartdns/upstream.lua b/package/luci/files/luci/model/cbi/smartdns/upstream.lua index 55541f1..382c857 100644 --- a/package/luci/files/luci/model/cbi/smartdns/upstream.lua +++ b/package/luci/files/luci/model/cbi/smartdns/upstream.lua @@ -39,6 +39,21 @@ o:value("https", translate("https")) o.default = "udp" o.rempty = false +---- SNI host name +o = s:option(Value, "host_name", translate("TLS SNI name"), translate("Sets the server name indication")) +o.default = "" +o.datatype = "hostname" +o.rempty = true +o:depends("type", "tls") +o:depends("type", "https") + +---- http host +o = s:option(Value, "http_host", translate("HTTP Host"), translate("Set the HTTP host used for the query. Use this parameter when the host of the URL address is an IP address.")) +o.default = "" +o.datatype = "hostname" +o.rempty = true +o:depends("type", "https") + ---- server group o = s:option(Value, "server_group", translate("Server Group"), translate("DNS Server group belongs to, used with nameserver, such as offlce, home.")) o.rmempty = true @@ -71,6 +86,7 @@ o.rempty = true o:depends("type", "tls") o:depends("type", "https") + ---- other args o = s:option(Value, "addition_arg", translate("Additional Server Args"), translate("Additional Args for upstream dns servers")) o.default = "" diff --git a/package/openwrt/files/etc/init.d/smartdns b/package/openwrt/files/etc/init.d/smartdns index d5de348..9e86325 100644 --- a/package/openwrt/files/etc/init.d/smartdns +++ b/package/openwrt/files/etc/init.d/smartdns @@ -136,6 +136,8 @@ load_server() config_get "port" "$section" "port" "" config_get "type" "$section" "type" "udp" config_get "ip" "$section" "ip" "" + config_get "host_name" "$section" "host_name" "" + config_get "http_host" "$section" "http_host" "" config_get "server_group" "$section" "server_group" "" config_get "blacklist_ip" "$section" "blacklist_ip" "0" config_get "check_edns" "$section" "check_edns" "0" @@ -165,6 +167,14 @@ load_server() fi fi + if [ ! -z "$host_name" ]; then + ADDITIONAL_ARGS="$ADDITIONAL_ARGS -host-name $host_name" + fi + + if [ ! -z "$http_host" ]; then + ADDITIONAL_ARGS="$ADDITIONAL_ARGS -http-host $http_host" + fi + if [ ! -z "$server_group" ]; then ADDITIONAL_ARGS="$ADDITIONAL_ARGS -group $server_group" fi diff --git a/src/dns_client.c b/src/dns_client.c index 351384e..5b7a59b 100644 --- a/src/dns_client.c +++ b/src/dns_client.c @@ -638,6 +638,9 @@ static int _dns_client_server_add(char *server_ip, struct addrinfo *gai, dns_ser case DNS_SERVER_HTTPS: { struct client_dns_server_flag_https *flag_https = &flags->https; spki_data_len = flag_https->spi_len; + if (flag_https->httphost[0] == 0) { + strncpy(flag_https->httphost, server_ip, DNS_MAX_CNAME_LEN); + } } break; case DNS_SERVER_TLS: { struct client_dns_server_flag_tls *flag_tls = &flags->tls; @@ -1290,7 +1293,7 @@ errout: return -1; } -static int _DNS_client_create_socket_tls(struct dns_server_info *server_info) +static int _DNS_client_create_socket_tls(struct dns_server_info *server_info, char *hostname) { int fd = 0; struct epoll_event event; @@ -1342,7 +1345,11 @@ static int _DNS_client_create_socket_tls(struct dns_server_info *server_info) if (server_info->ssl_session) { SSL_set_session(ssl, server_info->ssl_session); } + SSL_set_mode(ssl, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); + if (hostname[0] != 0) { + SSL_set_tlsext_host_name(ssl, hostname); + } memset(&event, 0, sizeof(event)); event.events = EPOLLIN | EPOLLOUT; @@ -1384,9 +1391,15 @@ 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 || server_info->type == DNS_SERVER_HTTPS) { - return _DNS_client_create_socket_tls(server_info); - } else { + } else if (server_info->type == DNS_SERVER_TLS) { + struct client_dns_server_flag_tls *flag_tls; + flag_tls = &server_info->flags.tls; + return _DNS_client_create_socket_tls(server_info, flag_tls->hostname); + } else if (server_info->type == DNS_SERVER_HTTPS) { + struct client_dns_server_flag_https *flag_https; + flag_https = &server_info->flags.https; + return _DNS_client_create_socket_tls(server_info, flag_https->hostname); + }else { return -1; } @@ -2112,7 +2125,7 @@ static int _dns_client_send_https(struct dns_server_info *server_info, void *pac "content-type: application/dns-message\r\n" "Content-Length: %d\r\n" "\r\n", - https_flag->path, https_flag->host, len); + https_flag->path, https_flag->httphost, len); memcpy(inpacket + http_len, packet, len); http_len += len; diff --git a/src/dns_client.h b/src/dns_client.h index c921a53..aaddb54 100644 --- a/src/dns_client.h +++ b/src/dns_client.h @@ -43,13 +43,14 @@ struct client_dns_server_flag_udp { struct client_dns_server_flag_tls { char spki[DNS_SERVER_SPKI_LEN]; int spi_len; - char host[DNS_MAX_CNAME_LEN]; + char hostname[DNS_MAX_CNAME_LEN]; }; struct client_dns_server_flag_https { char spki[DNS_SERVER_SPKI_LEN]; int spi_len; - char host[DNS_MAX_CNAME_LEN]; + char hostname[DNS_MAX_CNAME_LEN]; + char httphost[DNS_MAX_CNAME_LEN]; char path[DNS_MAX_CNAME_LEN]; }; diff --git a/src/dns_conf.c b/src/dns_conf.c index 6d439fa..e8f0754 100644 --- a/src/dns_conf.c +++ b/src/dns_conf.c @@ -171,6 +171,8 @@ static int _config_server(int argc, char *argv[], dns_server_type_t type, int de {"check-edns", no_argument, NULL, 'e'}, /* check edns */ {"spki-pin", required_argument, NULL, 'p'}, /* check SPKI pin */ {"check-ttl", required_argument, NULL, 't'}, /* check ttl */ + {"host-name", required_argument, NULL, 'h'}, /* host name */ + {"http-host", required_argument, NULL, 'H'}, /* http host */ {"group", required_argument, NULL, 'g'}, /* add to group */ {"exclude-default-group", no_argument, NULL, 'E'}, /* ecluse this from default group */ {NULL, no_argument, NULL, 0} @@ -190,6 +192,7 @@ static int _config_server(int argc, char *argv[], dns_server_type_t type, int de server->spki[0] = '\0'; server->path[0] = '\0'; server->hostname[0] = '\0'; + server->httphost[0] = '\0'; ip = argv[1]; @@ -198,6 +201,7 @@ static int _config_server(int argc, char *argv[], dns_server_type_t type, int de return -1; } strncpy(server->hostname, server->server, sizeof(server->hostname)); + strncpy(server->httphost, server->httphost, sizeof(server->hostname)); if (server->path[0] == 0) { strcpy(server->path, "/"); } @@ -247,6 +251,14 @@ static int _config_server(int argc, char *argv[], dns_server_type_t type, int de result_flag |= DNSSERVER_FLAG_CHECK_TTL; break; } + case 'h': { + strncpy(server->hostname, optarg, DNS_MAX_CNAME_LEN); + break; + } + case 'H': { + strncpy(server->httphost, optarg, DNS_MAX_CNAME_LEN); + break; + } case 'E': { server_flag |= SERVER_FLAG_EXCLUDE_DEFAULT; break; diff --git a/src/dns_conf.h b/src/dns_conf.h index c3824e4..f3f8e78 100644 --- a/src/dns_conf.h +++ b/src/dns_conf.h @@ -96,6 +96,7 @@ struct dns_servers { dns_server_type_t type; char spki[DNS_MAX_SPKI_LEN]; char hostname[DNS_MAX_CNAME_LEN]; + char httphost[DNS_MAX_CNAME_LEN]; char path[DNS_MAX_URL_LEN]; }; diff --git a/src/dns_server.c b/src/dns_server.c index c71dc5f..f87352d 100644 --- a/src/dns_server.c +++ b/src/dns_server.c @@ -1661,6 +1661,8 @@ static int _dns_server_recv(struct dns_server_conn *client, unsigned char *inpac request->qtype = qtype; } + tlog(TLOG_INFO, "query server %s from %s, qtype = %d\n", request->domain, name, qtype); + /* lookup domain rule */ request->domain_rule = _dns_server_get_domain_rule(request->domain); @@ -1715,8 +1717,6 @@ static int _dns_server_recv(struct dns_server_conn *client, unsigned char *inpac } } - tlog(TLOG_INFO, "query server %s from %s, qtype = %d\n", request->domain, name, qtype); - _dns_server_request_get(request); pthread_mutex_lock(&server.request_list_lock); list_add_tail(&request->list, &server.request_list); diff --git a/src/smartdns.c b/src/smartdns.c index 6d29d57..0aa3694 100644 --- a/src/smartdns.c +++ b/src/smartdns.c @@ -139,13 +139,14 @@ static int _smartdns_add_servers(void) case DNS_SERVER_HTTPS: { struct client_dns_server_flag_https *flag_http = &flags.https; flag_http->spi_len = dns_client_spki_decode(dns_conf_servers[i].spki, (unsigned char *)flag_http->spki); - strncpy(flag_http->host, dns_conf_servers[i].hostname, sizeof(flag_http->host)); + strncpy(flag_http->hostname, dns_conf_servers[i].hostname, sizeof(flag_http->hostname)); strncpy(flag_http->path, dns_conf_servers[i].path, sizeof(flag_http->path)); + strncpy(flag_http->httphost, dns_conf_servers[i].httphost, sizeof(flag_http->httphost)); } break; case DNS_SERVER_TLS: { struct client_dns_server_flag_tls *flag_tls = &flags.tls; flag_tls->spi_len = dns_client_spki_decode(dns_conf_servers[i].spki, (unsigned char *)flag_tls->spki); - strncpy(flag_tls->host, dns_conf_servers[i].hostname, sizeof(flag_tls->host)); + strncpy(flag_tls->hostname, dns_conf_servers[i].hostname, sizeof(flag_tls->hostname)); } break; break; case DNS_SERVER_TCP: