1 /*
2  * Copyright (c) 2015, 2021, Oracle and/or its affiliates.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License, version 2.0,
6  * as published by the Free Software Foundation.
7  *
8  * This program is also distributed with certain software (including
9  * but not limited to OpenSSL) that is licensed under separate terms,
10  * as designated in a particular file or component or in included license
11  * documentation.  The authors of MySQL hereby grant you an additional
12  * permission to link the program and your derivative works with the
13  * separately licensed software that they have included with MySQL.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License, version 2.0, for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
23  * 02110-1301  USA
24  */
25 
26 #ifndef _NGS_CLIENT_H_
27 #define _NGS_CLIENT_H_
28 
29 #include "ngs/protocol_encoder.h"
30 #include "ngs/protocol_decoder.h"
31 #include "ngs/memory.h"
32 #include "ngs/protocol/message.h"
33 #include "ngs/interface/client_interface.h"
34 #include "ngs/capabilities/configurator.h"
35 
36 #include "ngs_common/atomic.h"
37 #include "ngs_common/chrono.h"
38 #include "ngs_common/connection_vio.h"
39 
40 #ifndef WIN32
41 #include <netinet/in.h>
42 #endif
43 
44 
45 namespace ngs
46 {
47   class Server_interface;
48 
49   class Client : public Client_interface
50   {
51   public:
52     Client(Connection_ptr connection,
53            Server_interface &server,
54            Client_id client_id,
55            Protocol_monitor_interface &pmon);
56     virtual ~Client();
57 
get_session_exit_mutex()58     Mutex &get_session_exit_mutex() { return m_session_exit_mutex; }
session()59     ngs::shared_ptr<Session_interface> session() { return m_session; }
60 
61   public: // impl ngs::Client_interface
62     virtual void run(const bool skip_resolve_name);
63 
64     virtual void activate_tls();
65 
66     virtual void reset_accept_time();
67 
68     virtual void on_auth_timeout();
69     virtual void on_server_shutdown();
70 
server()71     virtual Server_interface &server() const { return m_server; }
connection()72     virtual Connection_vio  &connection() { return *m_connection; };
73 
74     virtual void on_session_auth_success(Session_interface &s);
75     virtual void on_session_close(Session_interface &s);
76     virtual void on_session_reset(Session_interface &s);
77 
78     virtual void disconnect_and_trigger_close();
79 
client_address()80     virtual const char *client_address() const { return m_client_addr.c_str(); }
client_hostname()81     virtual const char *client_hostname() const { return m_client_host.c_str(); }
client_id()82     virtual const char *client_id() const { return m_id; }
client_id_num()83     virtual Client_id client_id_num() const { return m_client_id; }
client_port()84     virtual int       client_port() const { return m_client_port; }
85 
get_state()86     virtual Client_state  get_state() const { return m_state.load(); };
87     virtual chrono::time_point get_accept_time() const;
88 
89   protected:
90     char m_id[2+sizeof(Client_id)*2+1]; // 64bits in hex, plus 0x plus \0
91     Client_id m_client_id;
92     Server_interface &m_server;
93     Connection_ptr m_connection;
94 
95     Message_decoder m_decoder;
96 
97     ngs::chrono::time_point m_accept_time;
98 
99     ngs::Memory_instrumented<Protocol_encoder>::Unique_ptr m_encoder;
100     std::string m_client_addr;
101     std::string m_client_host;
102     uint16      m_client_port;
103     ngs::atomic<Client_state> m_state;
104     ngs::atomic<bool> m_removed;
105 
106     ngs::shared_ptr<Session_interface> m_session;
107 
108     Protocol_monitor_interface &m_protocol_monitor;
109 
110     Mutex m_session_exit_mutex;
111 
112     enum {
113       Not_closing,
114       Close_net_error,
115       Close_error,
116       Close_reject,
117       Close_normal,
118       Close_connect_timeout
119     } m_close_reason;
120 
121     char* m_msg_buffer;
122     size_t m_msg_buffer_size;
123 
124     Request *read_one_message(Error_code &ret_error);
125 
126     virtual ngs::Capabilities_configurator *capabilities_configurator();
127     void get_capabilities(const Mysqlx::Connection::CapabilitiesGet &msg);
128     void set_capabilities(const Mysqlx::Connection::CapabilitiesSet &msg);
129 
130     void remove_client_from_server();
131 
132     void handle_message(Request &message);
133     virtual std::string resolve_hostname() = 0;
134     virtual void on_network_error(int error);
135 
136     Protocol_monitor_interface &get_protocol_monitor();
137 
138   private:
139     Client(const Client &);
140     Client &operator=(const Client &);
141 
142     void get_last_error(int &error_code, std::string &message);
143     void shutdown_connection();
144 
145     void on_client_addr(const bool skip_resolve_name);
146     void on_accept();
147     void on_kill(Session_interface &session);
148   };
149 
150 } // namespace ngs
151 
152 #endif
153