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 <cstdio>
00027 #include <memory>
00028 #include <netdb.h>
00029 #include <stdint.h>
00030 #include <sys/socket.h>
00031 #include <sys/time.h>
00032 #include <sys/types.h>
00033 #include <sys/un.h>
00034 #include <unistd.h>
00035
00036 #include <scalestack/kernel/module.h>
00037 #include <scalestack/kernel/option.h>
00038 #include <scalestack/network/datagram_service.h>
00039 #include <scalestack/network/local/local.h>
00040 #include <scalestack/network/local/datagram/socket.h>
00041 #include <scalestack/network/local/datagram/socket_service.h>
00042
00043 using namespace std;
00044
00045 namespace scalestack
00046 {
00047 namespace network
00048 {
00049 namespace local
00050 {
00051 namespace datagram
00052 {
00053
00054
00055
00056
00057
00058 void socket_service::local_options(kernel::module& module,
00059 const std::string& addresses)
00060 {
00061 module.add_option("addresses", _("List of local sockets to bind to."),
00062 "SOCKET[,SOCKET]...", addresses);
00063 }
00064
00065 void socket_service::peer_options(kernel::module& module,
00066 const std::string& addresses)
00067 {
00068 module.add_option("addresses", _("List of local sockets to send to."),
00069 "SOCKET[,SOCKET]...", addresses);
00070 }
00071
00072 socket_service::socket_service(kernel::module& module,
00073 std::auto_ptr<datagram_service> datagram_service):
00074 kernel::service(module),
00075 _datagram_service(datagram_service),
00076 _handler_service(module)
00077 {
00078 }
00079
00080 socket_service::~socket_service()
00081 {
00082 _handler_service.stop();
00083 }
00084
00085 void socket_service::add_socket(const struct addrinfo* local,
00086 const struct addrinfo* peer)
00087 {
00088 string local_address;
00089
00090 if (local != NULL)
00091 {
00092 local_address =
00093 reinterpret_cast<struct sockaddr_un*>(local->ai_addr)->sun_path;
00094 _module.log_info(_("Local datagram socket trying to bind to %s"),
00095 local_address.c_str());
00096 }
00097
00098 if (peer != NULL)
00099 {
00100 _module.log_info(_("Local datagram socket with peer %s"),
00101 reinterpret_cast<struct sockaddr_un*>(peer->ai_addr)->sun_path);
00102 }
00103
00104 auto_ptr<socket> new_socket(
00105 new socket(_handler_service, *_datagram_service, local, local_address,
00106 peer));
00107 new_socket->start();
00108 new_socket.release();
00109
00110 if (local != NULL)
00111 {
00112 _module.log_notice(_("Local datagram socket bound to %s"),
00113 reinterpret_cast<struct sockaddr_un*>(local->ai_addr)->sun_path);
00114 }
00115 }
00116
00117 void socket_service::add_local_sockets(void)
00118 {
00119 add_local_sockets(_module.get_option("addresses").get_value());
00120 }
00121
00122 void socket_service::add_local_sockets(const std::string& addresses)
00123 {
00124 string::size_type current = 0;
00125
00126 do
00127 {
00128 string::size_type next = addresses.find_first_of(",", current);
00129 string address = addresses.substr(current, next - current);
00130
00131 struct addrinfo addrinfo;
00132 struct sockaddr_un sockaddr;
00133 set_address(addrinfo, sockaddr, SOCK_DGRAM, address);
00134
00135 add_socket(&addrinfo, NULL);
00136
00137 current = addresses.find_first_not_of(",", next);
00138 }
00139 while (current != string::npos);
00140 }
00141
00142 void socket_service::add_peer_sockets(void)
00143 {
00144 add_peer_sockets(_module.get_option("addresses").get_value());
00145 }
00146
00147 void socket_service::add_peer_sockets(const std::string& addresses)
00148 {
00149 string::size_type current = 0;
00150
00151 do
00152 {
00153 string::size_type next = addresses.find_first_of(",", current);
00154 string address = addresses.substr(current, next - current);
00155
00156 struct addrinfo addrinfo;
00157 struct sockaddr_un sockaddr;
00158 set_address(addrinfo, sockaddr, SOCK_DGRAM, address);
00159
00160
00161 struct timeval tv;
00162 gettimeofday(&tv, 0);
00163 char local_address[64];
00164 snprintf(local_address, 64, "/tmp/local.%u.%u",
00165 static_cast<uint32_t>(tv.tv_sec),
00166 static_cast<uint32_t>(tv.tv_usec));
00167 struct addrinfo local_addrinfo;
00168 struct sockaddr_un local_sockaddr;
00169 unlink(local_address);
00170 set_address(local_addrinfo, local_sockaddr, SOCK_DGRAM, local_address);
00171 add_socket(&local_addrinfo, &addrinfo);
00172
00173 current = addresses.find_first_not_of(",", next);
00174 }
00175 while (current != string::npos);
00176 }
00177
00178 }
00179 }
00180 }
00181 }