00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00024 #include "config.h"
00025
00026 #include <cstring>
00027 #include <exception>
00028 #include <memory>
00029 #include <netdb.h>
00030
00031 #include <scalestack/kernel/module.h>
00032 #include <scalestack/kernel/option.h>
00033 #include <scalestack/network/ip/address_service.h>
00034 #include <scalestack/network/ip/tcp/connection.h>
00035 #include <scalestack/network/ip/tcp/connection_service.h>
00036
00037 using namespace std;
00038
00039 namespace scalestack
00040 {
00041 namespace network
00042 {
00043 namespace ip
00044 {
00045 namespace tcp
00046 {
00047
00052 class connection_address_service: public ip::address_service
00053 {
00054 public:
00055
00056 connection_address_service(kernel::module& module,
00057 event::handler_service& handler_service,
00058 stream_service& stream_service);
00059
00063 bool add_addresses(const struct addrinfo* addresses);
00064
00065 private:
00066
00067 event::handler_service& _handler_service;
00068 stream_service& _stream_service;
00069 };
00070
00071
00072
00073
00074
00075 void connection_service::options(kernel::module& module, const char* addresses)
00076 {
00077 module.add_option("addresses", _("List of host:port pairs to connect to."),
00078 "HOST[:PORT][,HOST[:PORT]]...", addresses);
00079 }
00080
00081 connection_service::connection_service(kernel::module& module,
00082 std::auto_ptr<stream_service> stream_service,
00083 const std::string& default_port):
00084 stream_service_provider(module, stream_service),
00085 _default_port(default_port)
00086 {
00087 }
00088
00089 connection_service::~connection_service()
00090 {
00091 _handler_service.stop();
00092 }
00093
00094 void connection_service::add_accepted(int file_descriptor,
00095 struct sockaddr& peer,
00096 socklen_t peer_size)
00097 {
00098 char host_name[NI_MAXHOST];
00099 char port_name[NI_MAXSERV];
00100
00101 int return_code = getnameinfo(&peer,
00102 peer_size,
00103 host_name, NI_MAXHOST,
00104 port_name, NI_MAXSERV,
00105 NI_NUMERICHOST | NI_NUMERICSERV);
00106 if (return_code != 0)
00107 _module.log_fatal(_("Failed getnameinfo: %s"), gai_strerror(return_code));
00108
00109 _module.log_notice(_("TCP connection accepted from %s:%s"), host_name,
00110 port_name);
00111
00112 auto_ptr<connection> new_connection(
00113 new connection(_handler_service, *_stream_service, file_descriptor));
00114 new_connection->start();
00115 new_connection.release();
00116 }
00117
00118 void connection_service::add_connections(void)
00119 {
00120 add_connections(_module.get_option("addresses").get_value());
00121 }
00122
00123 void connection_service::add_connections(const std::string& addresses)
00124 {
00125 struct addrinfo address_options;
00126
00127 memset(&address_options, 0, sizeof(struct addrinfo));
00128 address_options.ai_flags = AI_PASSIVE;
00129 address_options.ai_family = AF_UNSPEC;
00130 address_options.ai_socktype = SOCK_STREAM;
00131 address_options.ai_protocol = IPPROTO_TCP;
00132
00133 connection_address_service address_service(_module, _handler_service,
00134 *_stream_service);
00135 address_service.parse_addresses(addresses, false, _default_port,
00136 address_options);
00137 }
00138
00139
00140
00141
00142
00143 connection_address_service::connection_address_service(
00144 kernel::module& module,
00145 event::handler_service& handler_service,
00146 stream_service& stream_service):
00147 ip::address_service(module),
00148 _handler_service(handler_service),
00149 _stream_service(stream_service)
00150 {
00151 }
00152
00153 bool connection_address_service::add_addresses(const struct addrinfo* addresses)
00154 {
00155 auto_ptr<connection> new_connection(
00156 new connection(_handler_service, _stream_service, addresses));
00157 new_connection->start();
00158 new_connection.release();
00159 return false;
00160 }
00161
00162 }
00163 }
00164 }
00165 }