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); arg = grpc_channel_args_find(args, GRPC_ARG_ENABLE_CHANNELZ);
if (grpc_channel_arg_get_bool(arg, false)) { 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 = state->channelz_listen_socket =
grpc_core::MakeRefCounted<grpc_core::channelz::ListenSocketNode>( grpc_core::MakeRefCounted<grpc_core::channelz::ListenSocketNode>(
grpc_core::UniquePtr<char>(host), *port_num); grpc_core::UniquePtr<char>(gpr_strdup(addr)));
gpr_free(port);
socket_uuid = state->channelz_listen_socket->uuid(); socket_uuid = state->channelz_listen_socket->uuid();
} }

@ -38,7 +38,6 @@
#include "src/core/lib/compression/stream_compression.h" #include "src/core/lib/compression/stream_compression.h"
#include "src/core/lib/debug/stats.h" #include "src/core/lib/debug/stats.h"
#include "src/core/lib/gpr/env.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/gpr/string.h"
#include "src/core/lib/gprpp/memory.h" #include "src/core/lib/gprpp/memory.h"
#include "src/core/lib/http/parser.h" #include "src/core/lib/http/parser.h"
@ -397,39 +396,10 @@ static bool read_channel_args(grpc_chttp2_transport* t,
} }
} }
if (channelz_enabled) { 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 = t->channelz_socket =
grpc_core::MakeRefCounted<grpc_core::channelz::SocketNode>( grpc_core::MakeRefCounted<grpc_core::channelz::SocketNode>(
std::move(local), std::move(remote)); grpc_core::UniquePtr<char>(),
grpc_uri_destroy(uri); grpc_core::UniquePtr<char>(gpr_strdup(t->peer_string)));
} }
return enable_bdp; return enable_bdp;
} }

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

@ -229,45 +229,10 @@ class ServerNode : public BaseNode {
ChannelTrace trace_; 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 // Handles channelz bookkeeping for sockets
class SocketNode : public BaseNode { class SocketNode : public BaseNode {
public: public:
SocketNode(SocketAddress local, SocketAddress remote); SocketNode(UniquePtr<char> local, UniquePtr<char> remote);
~SocketNode() override {} ~SocketNode() override {}
grpc_json* RenderJson() override; grpc_json* RenderJson() override;
@ -297,23 +262,21 @@ class SocketNode : public BaseNode {
gpr_atm last_remote_stream_created_millis_ = 0; gpr_atm last_remote_stream_created_millis_ = 0;
gpr_atm last_message_sent_millis_ = 0; gpr_atm last_message_sent_millis_ = 0;
gpr_atm last_message_received_millis_ = 0; gpr_atm last_message_received_millis_ = 0;
SocketAddress local_; UniquePtr<char> local_;
SocketAddress remote_; UniquePtr<char> remote_;
}; };
// Handles channelz bookkeeping for listen sockets // Handles channelz bookkeeping for listen sockets
class ListenSocketNode : public BaseNode { class ListenSocketNode : public BaseNode {
public: public:
// ListenSocketNode takes ownership of host. // ListenSocketNode takes ownership of host.
// TODO(ncteisen): use SocketAddress to support more address types. ListenSocketNode(UniquePtr<char> local_addr);
ListenSocketNode(UniquePtr<char> host, int port);
~ListenSocketNode() override {} ~ListenSocketNode() override {}
grpc_json* RenderJson() override; grpc_json* RenderJson() override;
private: private:
UniquePtr<char> host_; UniquePtr<char> local_addr_;
int port_;
}; };
// Creation functions // Creation functions

Loading…
Cancel
Save