1#include <Interpreters/ClientInfo.h>
2#include <IO/ReadBuffer.h>
3#include <IO/WriteBuffer.h>
4#include <IO/ReadHelpers.h>
5#include <IO/WriteHelpers.h>
6#include <Core/Defines.h>
7#include <Common/getFQDNOrHostName.h>
8#include <Common/ClickHouseRevision.h>
9#include <Common/config_version.h>
10#include <port/unistd.h>
11
12
13namespace DB
14{
15
16namespace ErrorCodes
17{
18 extern const int LOGICAL_ERROR;
19}
20
21
22void ClientInfo::write(WriteBuffer & out, const UInt64 server_protocol_revision) const
23{
24 if (server_protocol_revision < DBMS_MIN_REVISION_WITH_CLIENT_INFO)
25 throw Exception("Logical error: method ClientInfo::write is called for unsupported server revision", ErrorCodes::LOGICAL_ERROR);
26
27 writeBinary(UInt8(query_kind), out);
28 if (empty())
29 return;
30
31 writeBinary(initial_user, out);
32 writeBinary(initial_query_id, out);
33 writeBinary(initial_address.toString(), out);
34
35 writeBinary(UInt8(interface), out);
36
37 if (interface == Interface::TCP)
38 {
39 writeBinary(os_user, out);
40 writeBinary(client_hostname, out);
41 writeBinary(client_name, out);
42 writeVarUInt(client_version_major, out);
43 writeVarUInt(client_version_minor, out);
44 writeVarUInt(client_revision, out);
45 }
46 else if (interface == Interface::HTTP)
47 {
48 writeBinary(UInt8(http_method), out);
49 writeBinary(http_user_agent, out);
50 }
51
52 if (server_protocol_revision >= DBMS_MIN_REVISION_WITH_QUOTA_KEY_IN_CLIENT_INFO)
53 writeBinary(quota_key, out);
54
55 if (interface == Interface::TCP)
56 {
57 if (server_protocol_revision >= DBMS_MIN_REVISION_WITH_VERSION_PATCH)
58 writeVarUInt(client_version_patch, out);
59 }
60}
61
62
63void ClientInfo::read(ReadBuffer & in, const UInt64 client_protocol_revision)
64{
65 if (client_protocol_revision < DBMS_MIN_REVISION_WITH_CLIENT_INFO)
66 throw Exception("Logical error: method ClientInfo::read is called for unsupported client revision", ErrorCodes::LOGICAL_ERROR);
67
68 UInt8 read_query_kind = 0;
69 readBinary(read_query_kind, in);
70 query_kind = QueryKind(read_query_kind);
71 if (empty())
72 return;
73
74 readBinary(initial_user, in);
75 readBinary(initial_query_id, in);
76
77 String initial_address_string;
78 readBinary(initial_address_string, in);
79 initial_address = Poco::Net::SocketAddress(initial_address_string);
80
81 UInt8 read_interface = 0;
82 readBinary(read_interface, in);
83 interface = Interface(read_interface);
84
85 if (interface == Interface::TCP)
86 {
87 readBinary(os_user, in);
88 readBinary(client_hostname, in);
89 readBinary(client_name, in);
90 readVarUInt(client_version_major, in);
91 readVarUInt(client_version_minor, in);
92 readVarUInt(client_revision, in);
93 }
94 else if (interface == Interface::HTTP)
95 {
96 UInt8 read_http_method = 0;
97 readBinary(read_http_method, in);
98 http_method = HTTPMethod(read_http_method);
99
100 readBinary(http_user_agent, in);
101 }
102
103 if (client_protocol_revision >= DBMS_MIN_REVISION_WITH_QUOTA_KEY_IN_CLIENT_INFO)
104 readBinary(quota_key, in);
105
106 if (interface == Interface::TCP)
107 {
108 if (client_protocol_revision >= DBMS_MIN_REVISION_WITH_VERSION_PATCH)
109 readVarUInt(client_version_patch, in);
110 else
111 client_version_patch = client_revision;
112 }
113}
114
115
116void ClientInfo::fillOSUserHostNameAndVersionInfo()
117{
118 os_user.resize(256, '\0');
119 if (0 == getlogin_r(os_user.data(), os_user.size() - 1))
120 os_user.resize(strlen(os_user.c_str()));
121 else
122 os_user.clear(); /// Don't mind if we cannot determine user login.
123
124 client_hostname = getFQDNOrHostName();
125
126 client_version_major = DBMS_VERSION_MAJOR;
127 client_version_minor = DBMS_VERSION_MINOR;
128 client_version_patch = DBMS_VERSION_PATCH;
129 client_revision = ClickHouseRevision::get();
130}
131
132
133}
134