00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <sys/stat.h>
00021 #include <sys/types.h>
00022 #include <sys/wait.h>
00023 #include <unistd.h>
00024 #include <stdio.h>
00025 #include <stdlib.h>
00026 #include <errno.h>
00027 #include <fcntl.h>
00028 #include "log.h"
00029 #include "hsms_signums.h"
00030 #include "hsms_cnx.h"
00031 #include "hsms_factory.h"
00032 #include "hsmsd_interface.h"
00033 #include "user_agent.h"
00034 #include "registrar.h"
00035
00036 #define REGISTRAR_LOG_LEVEL 20
00037
00038
00039 #define DIR_PERMS (S_IRWXU | S_IRGRP | S_IXGRP | S_IXOTH | S_IROTH)
00040 #define FIFO_PERMS (S_IRWXU | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)
00041
00042 using namespace freesecs;
00043
00044 extern hsms_factory_t hsms_factory;
00045
00046 hsmsd_client_registrar_t::hsmsd_client_registrar_t()
00047 {
00048 struct stat statbuf;
00049 pid_t childpid;
00050
00051 if(0 == stat(HSMSD_FIFO_DIR, &statbuf))
00052 {
00053 if(-1 == (childpid = fork()))
00054 {
00055 TRACE_ERROR("HSMSD: failed to fork");
00056 throw;
00057 }
00058
00059 if(0 == childpid)
00060 {
00061 execl("/bin/rm", "rm", "-rf", HSMSD_FIFO_DIR, NULL);
00062 exit(1);
00063 }
00064
00065 if(childpid != wait(NULL))
00066 {
00067 TRACE_ERROR("HSMSD: failed to wait for child completion");
00068 throw;
00069 }
00070 }
00071
00072 if(mkdir(HSMSD_FIFO_DIR, DIR_PERMS))
00073 {
00074 TRACE_ERROR("HSMSD: failed to create dir %s", HSMSD_FIFO_DIR);
00075 throw;
00076 }
00077
00078 mode_t old_umask = umask(~FIFO_PERMS);
00079
00080
00081 if(-1 == mkfifo(HSMSD_REGISTER_FIFO_IN, FIFO_PERMS) && (errno != EEXIST))
00082 {
00083 umask(old_umask);
00084 TRACE_ERROR("HSMSD: failed to create registering FIFO %s", HSMSD_REGISTER_FIFO);
00085 throw;
00086 }
00087 if(-1 == mkfifo(HSMSD_REGISTER_FIFO_OUT, FIFO_PERMS) &&(errno != EEXIST))
00088 {
00089 umask(old_umask);
00090 TRACE_ERROR("HSMSD: failed to create registering FIFO %s", HSMSD_REGISTER_FIFO);
00091 throw;
00092 }
00093
00094 umask(old_umask);
00095
00096 if(-1 == (_fd_in = open(HSMSD_REGISTER_FIFO_IN, O_RDWR)))
00097 {
00098 TRACE_ERROR("HSMSD: failed to open registering FIFO %s", HSMSD_REGISTER_FIFO);
00099 throw;
00100 }
00101 if(-1 == (_fd_out = open(HSMSD_REGISTER_FIFO_OUT, O_RDWR)))
00102 {
00103 TRACE_ERROR("HSMSD: failed to open registering FIFO %s", HSMSD_REGISTER_FIFO);
00104 throw;
00105 }
00106
00107 _ar = new async_reception_t(_fd_in, "hsms client registrar");
00108 _ar->data_recvd_signal.add_handler(this, &hsmsd_client_registrar_t::data_rcvd_handler);
00109 _ar->recv_error_signal.add_handler(this, &hsmsd_client_registrar_t::rcv_error_handler);
00110
00111 TRACE_DEBUG(REGISTRAR_LOG_LEVEL, "HSMSD: start receiving from %s...", HSMSD_REGISTER_FIFO);
00112 _ar->start_recv(®ister_req, sizeof(register_req));
00113 }
00114
00115 hsmsd_client_registrar_t::~hsmsd_client_registrar_t()
00116 {
00117 _ar->stop_recv();
00118 close(_fd_in);
00119 close(_fd_out);
00120 }
00121
00122 void
00123 hsmsd_client_registrar_t::process()
00124 {
00125 sleep(10);
00126 }
00127
00128 int
00129 hsmsd_client_registrar_t::data_rcvd_handler(const size_t& num_received)
00130 {
00131 TRACE_DEBUG(REGISTRAR_LOG_LEVEL, "HSMSD: received %d bytes from %s", num_received, HSMSD_REGISTER_FIFO);
00132 if(num_received == sizeof(register_req))
00133 {
00134 process_user_request();
00135 }
00136 else
00137 {
00138 TRACE_ERROR("HSMSD: received %d bytes from %s. Expected %d bytes.",
00139 num_received, HSMSD_REGISTER_FIFO, sizeof(register_req));
00140 }
00141 _ar->start_recv(®ister_req, sizeof(register_req));
00142 return 0;
00143 }
00144
00145 int
00146 hsmsd_client_registrar_t::rcv_error_handler(const int& err)
00147 {
00148 TRACE_DEBUG(REGISTRAR_LOG_LEVEL, "HSMSD: received err %d from %s", HSMSD_REGISTER_FIFO);
00149 return 0;
00150 }
00151
00152 template<typename T>
00153 struct compare_name : public std::binary_function<T, const char*, bool>
00154 {
00155 bool operator()(const T &t, const char *name) const
00156 {
00157 return 0 == strcmp(t->name(), name);
00158 }
00159 };
00160
00161
00162 void
00163 hsmsd_client_registrar_t::process_user_request()
00164 {
00165 hsmsd_register_rsp_t register_rsp;
00166
00167 char client_fifo_name_ctl_in[128],
00168 client_fifo_name_ctl_out[128],
00169 client_fifo_name_data_in[128],
00170 client_fifo_name_data_out[128];
00171
00172 register_rsp.rsp_code = hsmsd_register_rsp_t::REG_OK;
00173 snprintf(client_fifo_name_ctl_in, sizeof(client_fifo_name_ctl_in),
00174 HSMSD_CLIENT_FIFO_CTL_IN_PATTERN, register_req.cli_pid, rand()&0xff);
00175 snprintf(client_fifo_name_ctl_out, sizeof(client_fifo_name_ctl_out),
00176 HSMSD_CLIENT_FIFO_CTL_OUT_PATTERN, register_req.cli_pid, rand()&0xff);
00177 snprintf(client_fifo_name_data_in, sizeof(client_fifo_name_data_in),
00178 HSMSD_CLIENT_FIFO_DATA_IN_PATTERN, register_req.cli_pid, rand()&0xff);
00179 snprintf(client_fifo_name_data_out, sizeof(client_fifo_name_data_out),
00180 HSMSD_CLIENT_FIFO_DATA_OUT_PATTERN, register_req.cli_pid, rand()&0xff);
00181
00182
00183 snprintf(register_rsp.pipe_name_ctl_req,
00184 sizeof(register_rsp.pipe_name_ctl_req), client_fifo_name_ctl_in);
00185 snprintf(register_rsp.pipe_name_ctl_rsp,
00186 sizeof(register_rsp.pipe_name_ctl_rsp), client_fifo_name_ctl_out);
00187 snprintf(register_rsp.pipe_name_data_req,
00188 sizeof(register_rsp.pipe_name_data_req), client_fifo_name_data_in);
00189 snprintf(register_rsp.pipe_name_data_rsp,
00190 sizeof(register_rsp.pipe_name_data_rsp), client_fifo_name_data_out);
00191
00192
00193
00194 TRACE_DEBUG(REGISTRAR_LOG_LEVEL, "HSMSD: number of active: %d, number of passive: %d",
00195 hsms_factory.active.size(), hsms_factory.passive.size());
00196
00197 std::vector<hsms_factory_t::active_cnx_ptr_t>::iterator it_active =
00198 find_if(hsms_factory.active.begin(), hsms_factory.active.end(),
00199 std::bind2nd(compare_name<hsms_factory_t::active_cnx_ptr_t>(),
00200 register_req.cnx_name));
00201
00202 if(hsms_factory.active.end() != it_active)
00203 {
00204 _clients.push_back(pclient_t(new user_agent_t(client_fifo_name_ctl_in
00205 ,client_fifo_name_ctl_out
00206 ,client_fifo_name_data_in
00207 ,client_fifo_name_data_out
00208 ,*((user_agent_t::pcnx_t*)&*it_active))));
00209 }
00210 else
00211 {
00212 std::vector<hsms_factory_t::passive_cnx_ptr_t>::iterator it_passive =
00213 find_if(hsms_factory.passive.begin(), hsms_factory.passive.end(),
00214 std::bind2nd(compare_name<hsms_factory_t::passive_cnx_ptr_t>(),
00215 register_req.cnx_name));
00216
00217 if(hsms_factory.passive.end() != it_passive)
00218 {
00219 _clients.push_back(pclient_t(new user_agent_t(client_fifo_name_ctl_in
00220 ,client_fifo_name_ctl_out
00221 ,client_fifo_name_data_in
00222 ,client_fifo_name_data_out
00223 ,*((user_agent_t::pcnx_t*)&*it_passive))));
00224 }
00225 else
00226 {
00227 TRACE_ERROR("HSMSD: process_user_request: invalid cnx name: %s", register_req.cnx_name);
00228 register_rsp.rsp_code = hsmsd_register_rsp_t::REG_INVALID_NAME;
00229 }
00230 }
00231 if(sizeof(register_rsp) != write(_fd_out, ®ister_rsp, sizeof(register_rsp)))
00232 {
00233 TRACE_ERROR("HSMSD: process_user_request: error responding to register request");
00234 }
00235 }