You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by am...@apache.org on 2023/03/17 04:32:04 UTC
[trafficserver] branch master updated: Refresh SOCKs logic, remove IpMapConf (#9523)
This is an automated email from the ASF dual-hosted git repository.
amc pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficserver.git
The following commit(s) were added to refs/heads/master by this push:
new 61c56b19c Refresh SOCKs logic, remove IpMapConf (#9523)
61c56b19c is described below
commit 61c56b19c3bbfeb0e67de0fc64e172636de9c5d3
Author: Alan M. Carroll <am...@apache.org>
AuthorDate: Thu Mar 16 23:31:57 2023 -0500
Refresh SOCKs logic, remove IpMapConf (#9523)
* SOCKS: Update for libswoc, remove IpMap dependency.
* swoc: Remove IpMapConf
---
include/tscore/IpMapConf.h | 35 --------
iocore/net/P_Socks.h | 15 ++--
iocore/net/Socks.cc | 115 +++++++++++++------------
iocore/net/UnixNetProcessor.cc | 2 +-
src/tscore/IpMapConf.cc | 187 -----------------------------------------
src/tscore/Makefile.am | 1 -
6 files changed, 71 insertions(+), 284 deletions(-)
diff --git a/include/tscore/IpMapConf.h b/include/tscore/IpMapConf.h
deleted file mode 100644
index 7d229adf1..000000000
--- a/include/tscore/IpMapConf.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/** @file
-
- Loading @c IpMap from a configuration file.
-
- @section license License
-
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
-
-// Copied from IPRange.cc for backwards compatibility.
-
-#pragma once
-
-class IpMap; // declare in name only.
-
-// Returns 0 if successful, error string otherwise
-int read_addr(char *line, int n, int *i, sockaddr *addr, char *err);
-// Returns 0 if successful, error string otherwise
-char *Load_IpMap_From_File(IpMap *map, int fd, char const *key_str);
-// Returns 0 if successful, error string otherwise
-char *Load_IpMap_From_File(IpMap *map, FILE *f, char const *key_str);
diff --git a/iocore/net/P_Socks.h b/iocore/net/P_Socks.h
index 2f875c1e4..d924796af 100644
--- a/iocore/net/P_Socks.h
+++ b/iocore/net/P_Socks.h
@@ -22,12 +22,16 @@
*/
#pragma once
+
+#include "swoc/TextView.h"
+#include "swoc/swoc_ip.h"
+
#include "P_EventSystem.h"
#include "I_Socks.h"
+#include "tscpp/util/ts_errata.h"
#ifdef SOCKS_WITH_TS
#include "ParentSelection.h"
-#include "tscore/IpMap.h"
#endif
enum {
@@ -43,8 +47,7 @@ struct socks_conf_struct {
int server_connect_timeout = 0;
int socks_timeout = 100;
unsigned char default_version = 5;
- char *user_name_n_passwd = nullptr;
- int user_name_n_passwd_len = 0;
+ std::string user_name_n_passwd;
int per_server_connection_attempts = 1;
int connection_attempts = 0;
@@ -55,7 +58,7 @@ struct socks_conf_struct {
unsigned short http_port = 1080;
#ifdef SOCKS_WITH_TS
- IpMap ip_map;
+ swoc::IPRangeSet ip_addrs;
#endif
#ifndef SOCKS_WITH_TS
@@ -75,7 +78,9 @@ extern struct socks_conf_struct *g_socks_conf_stuff;
void start_SocksProxy(int port);
-int loadSocksAuthInfo(int fd, socks_conf_struct *socks_stuff);
+int loadSocksAuthInfo(swoc::TextView content, socks_conf_struct *socks_stuff);
+
+swoc::Errata loadSocksIPAddrs(swoc::TextView content, socks_conf_struct *socks_stuff);
// umm.. the following typedef should take _its own_ type as one of the args
// not possible with C
diff --git a/iocore/net/Socks.cc b/iocore/net/Socks.cc
index aceddf700..ecb282d57 100644
--- a/iocore/net/Socks.cc
+++ b/iocore/net/Socks.cc
@@ -30,11 +30,16 @@
duplicated in UnixNet.cc and NTNetProcessor.cc
*/
+#include "swoc/swoc_file.h"
+#include "swoc/bwf_std.h"
+#include "swoc/bwf_ex.h"
+
#include "P_Net.h"
#include "tscore/I_Layout.h"
#include "tscore/ink_sock.h"
#include "tscore/InkErrno.h"
-#include "tscore/IpMapConf.h"
+
+using namespace swoc::literals;
socks_conf_struct *g_socks_conf_stuff = nullptr;
@@ -460,8 +465,10 @@ loadSocksConfiguration(socks_conf_struct *socks_conf_stuff)
int socks_config_fd = -1;
ats_scoped_str config_pathname;
#ifdef SOCKS_WITH_TS
- char *tmp;
+ swoc::Errata errata;
#endif
+ std::error_code ec;
+ std::string config_text;
socks_conf_stuff->accept_enabled = 0; // initialize it INKqa08593
socks_conf_stuff->socks_needed = REC_ConfigReadInteger("proxy.config.socks.socks_needed");
@@ -506,28 +513,28 @@ loadSocksConfiguration(socks_conf_struct *socks_conf_stuff)
goto error;
}
- socks_config_fd = ::open(config_pathname, O_RDONLY);
-
- if (socks_config_fd < 0) {
- Error("SOCKS Config: could not open config file '%s'. SOCKS Turned off", (const char *)config_pathname);
+ config_text = swoc::file::load(swoc::file::path(config_pathname), ec);
+ if (ec) {
+ swoc::bwprint(config_text, "SOCK Config: Disabled, could not open config file \"{}\" {}", config_pathname, ec);
+ Error("%s", config_text.c_str());
goto error;
}
+
#ifdef SOCKS_WITH_TS
- tmp = Load_IpMap_From_File(&socks_conf_stuff->ip_map, socks_config_fd, "no_socks");
+ errata = loadSocksIPAddrs(config_text, socks_conf_stuff);
- if (tmp) {
- Error("SOCKS Config: Error while reading ip_range: %s.", tmp);
- ats_free(tmp);
+ if (!errata.is_ok()) {
+ swoc::bwprint(config_text, "SOCK Config: Error\n{}", errata);
+ Error("%s", config_text.c_str());
goto error;
}
#endif
- if (loadSocksAuthInfo(socks_config_fd, socks_conf_stuff) != 0) {
+ if (loadSocksAuthInfo(config_text, socks_conf_stuff) != 0) {
Error("SOCKS Config: Error while reading Socks auth info");
goto error;
}
Debug("Socks", "Socks Turned on");
- ::close(socks_config_fd);
return;
error:
@@ -540,60 +547,58 @@ error:
}
int
-loadSocksAuthInfo(int fd, socks_conf_struct *socks_stuff)
+loadSocksAuthInfo(swoc::TextView content, socks_conf_struct *socks_stuff)
{
- char c = '\0';
- char line[256] = {0}; // initialize all chars to nil
- char user_name[256] = {0};
- char passwd[256] = {0};
-
- if (lseek(fd, 0, SEEK_SET) < 0) {
- Warning("Can not seek on Socks configuration file\n");
- return -1;
- }
-
- bool end_of_file = false;
- do {
- int n = 0, rc;
- while (((rc = read(fd, &c, 1)) == 1) && (c != '\n') && (n < 254)) {
- line[n++] = c;
- }
- if (rc <= 0) {
- end_of_file = true;
- }
- line[n] = '\0';
-
- // coverity[secure_coding]
- rc = sscanf(line, " auth u %255s %255s ", user_name, passwd);
- if (rc >= 2) {
- int len1 = strlen(user_name);
- int len2 = strlen(passwd);
-
- Debug("Socks", "Read user_name(%s) and passwd(%s) from config file", user_name, passwd);
-
- socks_stuff->user_name_n_passwd_len = len1 + len2 + 2;
+ static constexpr swoc::TextView PREFIX = "auth u ";
+ std::string text;
- char *ptr = static_cast<char *>(ats_malloc(socks_stuff->user_name_n_passwd_len));
- ptr[0] = len1;
- memcpy(&ptr[1], user_name, len1);
- ptr[len1 + 1] = len2;
- memcpy(&ptr[len1 + 2], passwd, len2);
+ while (content.ltrim_if(&isspace)) {
+ auto line = content.take_prefix_at('\n');
- socks_stuff->user_name_n_passwd = ptr;
+ if (line.starts_with(PREFIX)) {
+ line.remove_prefix(PREFIX.size()).ltrim_if(&isspace);
+ auto user_name = line.take_prefix_if(&isspace);
+ auto password = line.take_prefix_if(&isspace);
- return 0;
+ if (!user_name.empty() && !password.empty()) {
+ Debug("Socks", "%s", swoc::bwprint(text, "Read auth credentials \"{}\" : \"{}\"", user_name, password).c_str());
+ swoc::bwprint(socks_stuff->user_name_n_passwd, "{}{}{}{}", char(user_name.size()), user_name, char(password.size()),
+ password);
+ }
}
- } while (!end_of_file);
-
+ }
return 0;
}
+swoc::Errata
+loadSocksIPAddrs(swoc::TextView content, socks_conf_struct *socks_stuff)
+{
+ static constexpr swoc::TextView PREFIX = "no_socks ";
+ std::string text;
+
+ while (content.ltrim_if(&isspace)) {
+ auto line = content.take_prefix_at('\n');
+ if (line.starts_with(PREFIX)) {
+ line.remove_prefix(PREFIX.size());
+ while (line.ltrim_if(&isspace)) {
+ auto token = line.take_prefix_at(',');
+ if (swoc::IPRange r; r.load(token)) {
+ socks_stuff->ip_addrs.mark(r);
+ } else {
+ return swoc::Errata(ERRATA_ERROR, "Invalid IP address range \"{}\"", token);
+ }
+ }
+ }
+ }
+ return {};
+}
+
int
socks5BasicAuthHandler(int event, unsigned char *p, void (**h_ptr)(void))
{
// for more info on Socks5 see RFC 1928
int ret = 0;
- char *pass_phrase = netProcessor.socks_conf_stuff->user_name_n_passwd;
+ char *pass_phrase = netProcessor.socks_conf_stuff->user_name_n_passwd.data();
switch (event) {
case SOCKS_AUTH_OPEN:
@@ -672,8 +677,8 @@ socks5PasswdAuthHandler(int event, unsigned char *p, void (**h_ptr)(void))
switch (event) {
case SOCKS_AUTH_OPEN:
- pass_phrase = netProcessor.socks_conf_stuff->user_name_n_passwd;
- pass_len = netProcessor.socks_conf_stuff->user_name_n_passwd_len;
+ pass_phrase = netProcessor.socks_conf_stuff->user_name_n_passwd.data();
+ pass_len = netProcessor.socks_conf_stuff->user_name_n_passwd.length();
ink_assert(pass_phrase);
p[0] = 1; // version
diff --git a/iocore/net/UnixNetProcessor.cc b/iocore/net/UnixNetProcessor.cc
index 35fae59f0..8ee1b65e7 100644
--- a/iocore/net/UnixNetProcessor.cc
+++ b/iocore/net/UnixNetProcessor.cc
@@ -200,7 +200,7 @@ UnixNetProcessor::connect_re_internal(Continuation *cont, sockaddr const *target
* we need to connect using socks server even
* if this ip is in no_socks list.
*/
- !socks_conf_stuff->ip_map.contains(target))
+ !socks_conf_stuff->ip_addrs.contains(swoc::IPAddr(target)))
#endif
);
SocksEntry *socksEntry = nullptr;
diff --git a/src/tscore/IpMapConf.cc b/src/tscore/IpMapConf.cc
deleted file mode 100644
index 51bcc5ea0..000000000
--- a/src/tscore/IpMapConf.cc
+++ /dev/null
@@ -1,187 +0,0 @@
-/** @file
-
- Loading @c IpMap from a configuration file.
-
- @section license License
-
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
-
-// Copied from IPRange.cc for backwards compatibility.
-
-#include "tscore/IpMap.h"
-#include "tscore/IpMapConf.h"
-#include "tscore/ink_memory.h"
-
-static size_t const ERR_STRING_LEN = 256;
-static size_t const MAX_LINE_SIZE = 2048;
-
-// Returns 0 if successful, 1 if failed
-// line Input text (source line).
-// n Amount of data in @a line.
-// i [in,out] Offset in line.
-// addr [out] Destination for address.
-// err Buffer for error string (must be ERR_STRING_LEN big).
-int
-read_addr(char *line, int n, int *i, sockaddr *addr, char *err)
-{
- int k;
- char dst[INET6_ADDRSTRLEN];
- char *src = line + *i;
- bool bracketed_p = false;
-
- // Allow enclosing brackets to be more consistent but
- // don't bother passing it to @c ntop.
- if ((*i < n) && ('[' == *src)) {
- ++*i, ++src, bracketed_p = true;
- }
-
- for (k = 0; k < INET6_ADDRSTRLEN && *i < n && (isxdigit(*src) || '.' == *src || ':' == *src); ++k, ++*i, ++src) {
- dst[k] = *src;
- }
-
- if (bracketed_p && (!(*i < n) || (']' != *src))) {
- snprintf(err, ERR_STRING_LEN, "Unclosed brackets");
- return EINVAL;
- }
-
- if (k == sizeof(dst)) {
- snprintf(err, ERR_STRING_LEN, "IP address too long");
- return EINVAL;
- }
-
- dst[k] = '\0';
- if (0 != ats_ip_pton(dst, addr)) {
- snprintf(err, ERR_STRING_LEN, "IP address '%s' improperly formatted", dst);
- return EINVAL;
- }
- return 0;
-}
-
-char *
-Load_IpMap_From_File(IpMap *map, int fd, const char *key_str)
-{
- char *zret = nullptr;
- int fd2 = dup(fd); // dup to avoid closing the original file.
- FILE *f = nullptr;
-
- if (fd2 >= 0) {
- f = fdopen(fd2, "r");
- }
-
- if (f != nullptr) {
- zret = Load_IpMap_From_File(map, f, key_str);
- fclose(f);
- } else {
- zret = static_cast<char *>(ats_malloc(ERR_STRING_LEN));
- snprintf(zret, ERR_STRING_LEN, "Unable to reopen file descriptor as stream %d:%s", errno, strerror(errno));
- }
- return zret;
-}
-
-// Skip space in line, returning true if more data is available
-// (not end of line).
-//
-// line Source line.
-// n Line length.
-// offset Current offset
-static inline bool
-skip_space(char *line, int n, int &offset)
-{
- while (offset < n && isspace(line[offset])) {
- ++offset;
- }
- return offset < n;
-}
-
-// Returns 0 if successful, error string otherwise
-char *
-Load_IpMap_From_File(IpMap *map, FILE *f, const char *key_str)
-{
- int i, n, line_no;
- int key_len = strlen(key_str);
- IpEndpoint laddr, raddr;
- char line[MAX_LINE_SIZE];
- char err_buff[ERR_STRING_LEN];
-
- // First hardcode 127.0.0.1 into the table
- map->mark(INADDR_LOOPBACK);
-
- line_no = 0;
- while (fgets(line, MAX_LINE_SIZE, f)) {
- ++line_no;
- n = strlen(line);
- // Find first white space which terminates the line key.
- for (i = 0; i < n && !isspace(line[i]); ++i) {
- ;
- }
- if (i != key_len || 0 != strncmp(line, key_str, key_len)) {
- continue;
- }
- // Now look for IP address
- while (true) {
- if (!skip_space(line, n, i)) {
- break;
- }
-
- if (0 != read_addr(line, n, &i, &laddr.sa, err_buff)) {
- char *error_str = static_cast<char *>(ats_malloc(ERR_STRING_LEN));
- snprintf(error_str, ERR_STRING_LEN, "Invalid input configuration (%s) at line %d offset %d - '%s'", err_buff, line_no, i,
- line);
- return error_str;
- }
-
- if (!skip_space(line, n, i) || line[i] == ',') {
- // You have read an IP address. Enter it in the table
- map->mark(&laddr);
- if (i == n) {
- break;
- } else {
- ++i;
- }
- } else if (line[i] == '-') {
- // What you have just read is the start of the range,
- // Now, read the end of the IP range
- ++i;
- if (!skip_space(line, n, i)) {
- char *error_str = static_cast<char *>(ats_malloc(ERR_STRING_LEN));
- snprintf(error_str, ERR_STRING_LEN, "Invalid input (unterminated range) at line %d offset %d - '%s'", line_no, i, line);
- return error_str;
- } else if (0 != read_addr(line, n, &i, &raddr.sa, err_buff)) {
- char *error_str = static_cast<char *>(ats_malloc(ERR_STRING_LEN));
- snprintf(error_str, ERR_STRING_LEN, "Invalid input (%s) at line %d offset %d - '%s'", err_buff, line_no, i, line);
- return error_str;
- }
- map->mark(&laddr.sa, &raddr.sa);
- if (!skip_space(line, n, i)) {
- break;
- }
- if (line[i] != ',') {
- char *error_str = static_cast<char *>(ats_malloc(ERR_STRING_LEN));
- snprintf(error_str, ERR_STRING_LEN, "Invalid input (expecting comma) at line %d offset %d - '%s'", line_no, i, line);
- return error_str;
- }
- ++i;
- } else {
- char *error_str = static_cast<char *>(ats_malloc(ERR_STRING_LEN));
- snprintf(error_str, ERR_STRING_LEN, "Invalid input (expecting dash or comma) at line %d offset %d", line_no, i);
- return error_str;
- }
- }
- }
- return nullptr;
-}
diff --git a/src/tscore/Makefile.am b/src/tscore/Makefile.am
index 941a3625d..4cd1fa6d2 100644
--- a/src/tscore/Makefile.am
+++ b/src/tscore/Makefile.am
@@ -105,7 +105,6 @@ libtscore_la_SOURCES = \
ink_time.cc \
ink_uuid.cc \
IpMap.cc \
- IpMapConf.cc \
JeMiAllocator.cc \
Layout.cc \
llqueue.cc \