Handle uri parsing in channelz module

pull/17050/head
ncteisen 6 years ago
parent 1a3c2d3e3a
commit fa4894e110
  1. 7
      src/core/ext/transport/chttp2/server/chttp2_server.cc
  2. 34
      src/core/ext/transport/chttp2/transport/chttp2_transport.cc
  3. 100
      src/core/lib/channel/channelz.cc
  4. 47
      src/core/lib/channel/channelz.h

@ -367,14 +367,9 @@ grpc_error* grpc_chttp2_server_add_port(grpc_server* server, const char* addr,
arg = grpc_channel_args_find(args, GRPC_ARG_ENABLE_CHANNELZ);
if (grpc_channel_arg_get_bool(arg, false)) {
char* host;
char* port;
gpr_split_host_port(addr, &host, &port);
// allocated host's ownership is passed to ListenSocketNode.
state->channelz_listen_socket =
grpc_core::MakeRefCounted<grpc_core::channelz::ListenSocketNode>(
grpc_core::UniquePtr<char>(host), *port_num);
gpr_free(port);
grpc_core::UniquePtr<char>(gpr_strdup(addr)));
socket_uuid = state->channelz_listen_socket->uuid();
}

@ -38,7 +38,6 @@
#include "src/core/lib/compression/stream_compression.h"
#include "src/core/lib/debug/stats.h"
#include "src/core/lib/gpr/env.h"
#include "src/core/lib/gpr/host_port.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gprpp/memory.h"
#include "src/core/lib/http/parser.h"
@ -397,39 +396,10 @@ static bool read_channel_args(grpc_chttp2_transport* t,
}
}
if (channelz_enabled) {
grpc_core::channelz::SocketAddress remote;
grpc_core::channelz::SocketAddress local;
char* host = nullptr;
int port_num = -1;
// try to pick out just the host port (maybe trims off scheme prefix).
grpc_uri* uri = grpc_uri_parse(t->peer_string, true);
// if peer string was a valid URI, we can use our lib to do the trimming.
// TODO(ncteisen): handle UDS address.
if (uri != nullptr) {
const char* host_port = uri->path;
if (*host_port == '/') ++host_port;
char* port;
GPR_ASSERT(gpr_split_host_port(host_port, &host, &port));
if (port != nullptr) {
port_num = atoi(port);
}
remote.set_blob(gpr_string_base64_encode(host));
remote.set_port(port_num);
remote.set_type(
grpc_core::channelz::SocketAddress::AddressType::kTcpAddress);
gpr_free(host);
gpr_free(port);
} else {
// if peer string is not a valid URI, just use the entire string to
// surface that info.
remote.set_blob(gpr_strdup(t->peer_string));
remote.set_type(grpc_core::channelz::SocketAddress::AddressType::
kDirectChannelAddress);
}
t->channelz_socket =
grpc_core::MakeRefCounted<grpc_core::channelz::SocketNode>(
std::move(local), std::move(remote));
grpc_uri_destroy(uri);
grpc_core::UniquePtr<char>(),
grpc_core::UniquePtr<char>(gpr_strdup(t->peer_string)));
}
return enable_bdp;
}

@ -30,6 +30,7 @@
#include "src/core/lib/channel/channelz_registry.h"
#include "src/core/lib/channel/status_util.h"
#include "src/core/lib/gpr/host_port.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gpr/useful.h"
#include "src/core/lib/gprpp/memory.h"
@ -39,6 +40,7 @@
#include "src/core/lib/surface/channel.h"
#include "src/core/lib/surface/server.h"
#include "src/core/lib/transport/error_utils.h"
#include "src/core/lib/uri/uri_parser.h"
namespace grpc_core {
namespace channelz {
@ -277,62 +279,59 @@ grpc_json* ServerNode::RenderJson() {
return top_level_json;
}
SocketAddress::SocketAddress() : type_(AddressType::kUnset), port_(-1) {}
SocketAddress::SocketAddress(SocketAddress&& other) {
type_ = other.type_;
port_ = other.port_;
blob_.reset((other.blob_.release()));
}
void SocketAddress::PopulateJson(const char* name, grpc_json* json) {
if (type_ == AddressType::kUnset) {
return;
}
static void PopulateSocketAddressJson(grpc_json* json, const char* name,
const char* addr_str) {
if (addr_str == nullptr) return;
grpc_json* json_iterator = nullptr;
json_iterator = grpc_json_create_child(json_iterator, json, name, nullptr,
GRPC_JSON_OBJECT, false);
json = json_iterator;
json_iterator = nullptr;
switch (type_) {
case AddressType::kTcpAddress:
json_iterator =
grpc_json_create_child(json_iterator, json, "tcpip_address", nullptr,
GRPC_JSON_OBJECT, false);
json = json_iterator;
json_iterator = nullptr;
json_iterator =
grpc_json_add_number_string_child(json, json_iterator, "port", port_);
json_iterator =
grpc_json_create_child(json_iterator, json, "ip_address", blob_.get(),
GRPC_JSON_STRING, false);
break;
case AddressType::kUdsAddress:
int port_num = -1;
grpc_uri* uri = grpc_uri_parse(addr_str, true);
if (uri != nullptr && (strcmp(uri->scheme, "fd") != 0)) {
const char* host_port = uri->path;
if (*host_port == '/') ++host_port;
if (strcmp(uri->scheme, "unix") == 0) {
json_iterator = grpc_json_create_child(json_iterator, json, "uds_address",
nullptr, GRPC_JSON_OBJECT, false);
json = json_iterator;
json_iterator = nullptr;
json_iterator =
grpc_json_create_child(json_iterator, json, "filename", blob_.get(),
GRPC_JSON_STRING, false);
break;
case AddressType::kDirectChannelAddress:
grpc_json_create_child(json_iterator, json, "filename",
gpr_strdup(host_port), GRPC_JSON_STRING, true);
} else {
char* host = nullptr;
char* port = nullptr;
GPR_ASSERT(gpr_split_host_port(host_port, &host, &port));
if (port != nullptr) {
port_num = atoi(port);
}
char* b64_host = gpr_string_base64_encode(host);
json_iterator =
grpc_json_create_child(json_iterator, json, "other_address", nullptr,
grpc_json_create_child(json_iterator, json, "tcpip_address", nullptr,
GRPC_JSON_OBJECT, false);
json = json_iterator;
json_iterator = nullptr;
json_iterator = grpc_json_create_child(
json_iterator, json, "name", blob_.get(), GRPC_JSON_STRING, false);
break;
break;
default:
GPR_UNREACHABLE_CODE(GPR_ASSERT(0));
break;
json_iterator = grpc_json_add_number_string_child(json, json_iterator,
"port", port_num);
json_iterator = grpc_json_create_child(json_iterator, json, "ip_address",
b64_host, GRPC_JSON_STRING, true);
gpr_free(host);
gpr_free(port);
}
} else {
json_iterator = grpc_json_create_child(json_iterator, json, "other_address",
nullptr, GRPC_JSON_OBJECT, false);
json = json_iterator;
json_iterator = nullptr;
json_iterator = grpc_json_create_child(json_iterator, json, "name",
addr_str, GRPC_JSON_STRING, false);
}
grpc_uri_destroy(uri);
}
SocketNode::SocketNode(SocketAddress local, SocketAddress remote)
SocketNode::SocketNode(UniquePtr<char> local, UniquePtr<char> remote)
: BaseNode(EntityType::kSocket),
local_(std::move(local)),
remote_(std::move(remote)) {}
@ -374,8 +373,8 @@ grpc_json* SocketNode::RenderJson() {
json_iterator = grpc_json_add_number_string_child(json, json_iterator,
"socketId", uuid());
json = top_level_json;
remote_.PopulateJson("remote", json);
local_.PopulateJson("local", json);
PopulateSocketAddressJson(json, "remote", remote_.get());
PopulateSocketAddressJson(json, "local", local_.get());
// reset json iterators to top level object
json = top_level_json;
json_iterator = nullptr;
@ -435,8 +434,8 @@ grpc_json* SocketNode::RenderJson() {
return top_level_json;
}
ListenSocketNode::ListenSocketNode(UniquePtr<char> host, int port)
: BaseNode(EntityType::kSocket), host_(std::move(host)), port_(port) {}
ListenSocketNode::ListenSocketNode(UniquePtr<char> local_addr)
: BaseNode(EntityType::kSocket), local_addr_(std::move(local_addr)) {}
grpc_json* ListenSocketNode::RenderJson() {
// We need to track these three json objects to build our object
@ -450,20 +449,7 @@ grpc_json* ListenSocketNode::RenderJson() {
json_iterator = nullptr;
json_iterator = grpc_json_add_number_string_child(json, json_iterator,
"socketId", uuid());
json = top_level_json;
json_iterator = nullptr;
json_iterator = grpc_json_create_child(json_iterator, json, "local", nullptr,
GRPC_JSON_OBJECT, false);
json = json_iterator;
json_iterator = nullptr;
json_iterator = grpc_json_create_child(json_iterator, json, "tcpip_address",
nullptr, GRPC_JSON_OBJECT, false);
json = json_iterator;
json_iterator = nullptr;
json_iterator =
grpc_json_add_number_string_child(json, json_iterator, "port", port_);
json_iterator = grpc_json_create_child(json_iterator, json, "ip_address",
host_.get(), GRPC_JSON_STRING, false);
PopulateSocketAddressJson(json, "local", local_addr_.get());
return top_level_json;
}

@ -229,45 +229,10 @@ class ServerNode : public BaseNode {
ChannelTrace trace_;
};
// helper class for holding and rendering the information about a particular
// socket's address
class SocketAddress {
public:
enum class AddressType {
kUnset,
kTcpAddress,
kUdsAddress,
kDirectChannelAddress,
};
SocketAddress();
SocketAddress(SocketAddress&& other);
void PopulateJson(const char* name, grpc_json* json);
void set_blob(char* blob) { blob_.reset(blob); }
void set_port(int port) { port_ = port; }
void set_type(AddressType type) { type_ = type; }
const char* blob_view() { return blob_.get(); }
int port() { return port_; }
AddressType type() { return type_; }
private:
AddressType type_;
// this holds different information for different address types:
// kTcpAddress = host
// kUdsAddress = filename
// kDirectChannelAddress = name (which is fd num)
UniquePtr<char> blob_;
// used for kTcpAddress, otherwise -1
int port_;
};
// Handles channelz bookkeeping for sockets
class SocketNode : public BaseNode {
public:
SocketNode(SocketAddress local, SocketAddress remote);
SocketNode(UniquePtr<char> local, UniquePtr<char> remote);
~SocketNode() override {}
grpc_json* RenderJson() override;
@ -297,23 +262,21 @@ class SocketNode : public BaseNode {
gpr_atm last_remote_stream_created_millis_ = 0;
gpr_atm last_message_sent_millis_ = 0;
gpr_atm last_message_received_millis_ = 0;
SocketAddress local_;
SocketAddress remote_;
UniquePtr<char> local_;
UniquePtr<char> remote_;
};
// Handles channelz bookkeeping for listen sockets
class ListenSocketNode : public BaseNode {
public:
// ListenSocketNode takes ownership of host.
// TODO(ncteisen): use SocketAddress to support more address types.
ListenSocketNode(UniquePtr<char> host, int port);
ListenSocketNode(UniquePtr<char> local_addr);
~ListenSocketNode() override {}
grpc_json* RenderJson() override;
private:
UniquePtr<char> host_;
int port_;
UniquePtr<char> local_addr_;
};
// Creation functions

Loading…
Cancel
Save