return 1;
}
+static int net_tls_client_clear(lua_State *L)
+{
+ struct engine *engine = engine_luaget(L);
+ if (!engine) {
+ return 0;
+ }
+
+ struct network *net = &engine->net;
+ if (!net) {
+ return 0;
+ }
+
+ if (lua_gettop(L) != 1 || !lua_isstring(L, 1)) {
+ format_error(L, "net.tls_client_clear() requires one parameter (\"address\")");
+ lua_error(L);
+ }
+
+ const char *full_addr = lua_tostring(L, 1);
+
+ char addr[INET6_ADDRSTRLEN];
+ uint16_t port = 0;
+ if (kr_straddr_split(full_addr, addr, sizeof(addr), &port) != kr_ok()) {
+ format_error(L, "invalid IP address");
+ lua_error(L);
+ }
+
+ if (port == 0) {
+ port = 853;
+ }
+
+ int r = tls_client_params_clear(&net->tls_client_params, addr, port);
+ if (r != 0) {
+ lua_pushstring(L, kr_strerror(r));
+ lua_error(L);
+ }
+
+ lua_pushboolean(L, true);
+ return 1;
+}
+
static int net_tls_padding(lua_State *L)
{
struct engine *engine = engine_luaget(L);
{ "tls", net_tls },
{ "tls_server", net_tls },
{ "tls_client", net_tls_client },
+ { "tls_client_clear", net_tls_client_clear },
{ "tls_padding", net_tls_padding },
{ "tls_sticket_secret", net_tls_sticket_secret_string },
{ "tls_sticket_secret_file", net_tls_sticket_secret_file },
return client_paramlist_entry_free(entry);
}
+struct tls_client_paramlist_entry *tls_client_try_upgrade(map_t *tls_client_paramlist,
+ const struct sockaddr *addr)
+{
+ /* Opportunistic upgrade from port 53 -> 853 */
+ if (kr_inaddr_port(addr) != KR_DNS_PORT) {
+ return NULL;
+ }
+
+ static char key[INET6_ADDRSTRLEN + 6];
+ size_t keylen = sizeof(key);
+ if (kr_inaddr_str(addr, key, &keylen) != 0) {
+ return NULL;
+ }
+
+ /* Rewrite 053 -> 853 */
+ strcpy(key + keylen - 3, "853");
+
+ return map_get(tls_client_paramlist, key);
+}
+
+int tls_client_params_clear(map_t *tls_client_paramlist, const char *addr, uint16_t port)
+{
+ if (!tls_client_paramlist || !addr) {
+ return kr_error(EINVAL);
+ }
+
+ /* Parameters are OK */
+
+ char key[INET6_ADDRSTRLEN + 6];
+ size_t keylen = sizeof(key);
+ if (kr_straddr_join(addr, port, key, &keylen) != kr_ok()) {
+ return kr_error(EINVAL);
+ }
+
+ struct tls_client_paramlist_entry *entry = map_get(tls_client_paramlist, key);
+ if (entry != NULL) {
+ client_paramlist_entry_clear(NULL, (void *)entry, NULL);
+ map_del(tls_client_paramlist, key);
+ }
+
+ return kr_ok();
+}
+
int tls_client_params_set(map_t *tls_client_paramlist,
const char *addr, uint16_t port,
const char *param, tls_client_param_t param_type)
struct tls_client_paramlist_entry *tls_client_try_upgrade(map_t *tls_client_paramlist,
const struct sockaddr *addr);
+/*! Clear (remove) TLS parameters for given address. */
+int tls_client_params_clear(map_t *tls_client_paramlist, const char *addr, uint16_t port);
+
/*! Set TLS authentication parameters for given address.
* Note: hostnames must be imported before ca files,
* otherwise ca files will not be imported at all.
choice += 1;
}
+ /* Upgrade to TLS if the upstream address is configured as DoT capable. */
+ struct engine *engine = ctx->worker->engine;
+ struct network *net = &engine->net;
+ const struct sockaddr *addr = packet_source ? packet_source : task->addrlist;
+ struct tls_client_paramlist_entry *tls_entry = NULL;
+ if (kr_inaddr_port(task->addrlist) == KR_DNS_PORT) {
+ tls_entry = tls_client_try_upgrade(&net->tls_client_params, task->addrlist);
+ if (tls_entry != NULL) {
+ kr_inaddr_set_port(task->addrlist, KR_DNS_TLS_PORT);
+ sock_type = SOCK_STREAM;
+ }
+ } else if (sock_type == SOCK_STREAM) {
+ const char *key = tcpsess_key(addr);
+ tls_entry = map_get(&net->tls_client_params, key);
+ }
+
int ret = 0;
if (sock_type == SOCK_DGRAM) {
/* Start fast retransmit with UDP. */