Add AddressType

pull/17050/head
ncteisen 6 years ago
parent 48c3c964b1
commit 1e64fa629c
  1. 14
      src/core/ext/transport/chttp2/transport/chttp2_transport.cc
  2. 77
      src/core/lib/channel/channelz.cc
  3. 42
      src/core/lib/channel/channelz.h
  4. 45
      src/core/lib/gpr/string.cc
  5. 3
      src/core/lib/gpr/string.h

@ -397,11 +397,14 @@ 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;
@ -410,15 +413,22 @@ static bool read_channel_args(grpc_chttp2_transport* t,
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.
host = gpr_strdup(t->peer_string);
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>(
grpc_core::UniquePtr<char>(host), port_num);
std::move(local), std::move(remote));
grpc_uri_destroy(uri);
}
return enable_bdp;

@ -277,10 +277,65 @@ grpc_json* ServerNode::RenderJson() {
return top_level_json;
}
SocketNode::SocketNode(UniquePtr<char> remote_host, int remote_port)
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;
}
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:
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:
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", blob_.get(), GRPC_JSON_STRING, false);
break;
break;
default:
GPR_UNREACHABLE_CODE(GPR_ASSERT(0));
break;
}
}
SocketNode::SocketNode(SocketAddress local, SocketAddress remote)
: BaseNode(EntityType::kSocket),
remote_host_(std::move(remote_host)),
remote_port_(remote_port) {}
local_(std::move(local)),
remote_(std::move(remote)) {}
void SocketNode::RecordStreamStartedFromLocal() {
gpr_atm_no_barrier_fetch_add(&streams_started_, static_cast<gpr_atm>(1));
@ -319,20 +374,8 @@ grpc_json* SocketNode::RenderJson() {
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, "remote", 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",
remote_port_);
json_iterator =
grpc_json_create_child(json_iterator, json, "ip_address",
remote_host_.get(), GRPC_JSON_STRING, false);
remote_.PopulateJson("remote", json);
local_.PopulateJson("local", json);
// reset json iterators to top level object
json = top_level_json;
json_iterator = nullptr;

@ -229,10 +229,45 @@ 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(UniquePtr<char> remote_host, int remote_port);
SocketNode(SocketAddress local, SocketAddress remote);
~SocketNode() override {}
grpc_json* RenderJson() override;
@ -262,14 +297,15 @@ 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;
UniquePtr<char> remote_host_;
int remote_port_;
SocketAddress local_;
SocketAddress 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() override {}

@ -156,6 +156,51 @@ int gpr_parse_bytes_to_uint32(const char* buf, size_t len, uint32_t* result) {
return 1;
}
static const char alphabet[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static const uint8_t tail_xtra[3] = {0, 2, 3};
char* gpr_string_base64_encode(const char* in) {
size_t in_len = strlen(in);
size_t in_triplets = in_len / 3;
size_t tail_case = in_len % 3;
size_t out_length = in_triplets * 4 + tail_xtra[tail_case];
char* output = static_cast<char*>(gpr_malloc(out_length + 1));
char* out = output;
size_t i;
/* encode full triplets */
for (i = 0; i < in_triplets; i++) {
out[0] = alphabet[in[0] >> 2];
out[1] = alphabet[((in[0] & 0x3) << 4) | (in[1] >> 4)];
out[2] = alphabet[((in[1] & 0xf) << 2) | (in[2] >> 6)];
out[3] = alphabet[in[2] & 0x3f];
out += 4;
in += 3;
}
/* encode the remaining bytes */
switch (tail_case) {
case 0:
break;
case 1:
out[0] = alphabet[in[0] >> 2];
out[1] = alphabet[(in[0] & 0x3) << 4];
out += 2;
in += 1;
break;
case 2:
out[0] = alphabet[in[0] >> 2];
out[1] = alphabet[((in[0] & 0x3) << 4) | (in[1] >> 4)];
out[2] = alphabet[(in[1] & 0xf) << 2];
out += 3;
in += 2;
break;
}
out[0] = '\0';
return output;
}
void gpr_reverse_bytes(char* str, int len) {
char *p1, *p2;
for (p1 = str, p2 = str + len - 1; p2 > p1; ++p1, --p2) {

@ -41,6 +41,9 @@ char* gpr_dump(const char* buf, size_t len, uint32_t flags);
int gpr_parse_bytes_to_uint32(const char* data, size_t length,
uint32_t* result);
/* returns allocated string with the base64 encoding of in */
char* gpr_string_base64_encode(const char* in);
/* Minimum buffer size for calling ltoa */
#define GPR_LTOA_MIN_BUFSIZE (3 * sizeof(long))

Loading…
Cancel
Save