libutil++  1.9.3
 All Classes Functions Variables
client.cpp
1 /*
2 ** libutil++
3 ** $Id: client.cpp 1653 2016-02-28 19:54:59Z sella $
4 ** Copyright (c) 2011-2016 Digital Genesis, LLC. All Rights Reserved.
5 ** Released under the LGPL Version 2.1 License.
6 ** http://www.digitalgenesis.com
7 */
8 
9 static const char rcsid[] __attribute__((used)) = "$Id: client.cpp 1653 2016-02-28 19:54:59Z sella $";
10 
11 #include "test.h"
12 
13 #include <stdio.h>
14 #include <signal.h>
15 #include <stdlib.h>
16 #include <unistd.h>
17 #include <pthread.h>
18 
19 #include <mutex>
20 #include <condition_variable>
21 
22 #include "alias.h"
23 #include "version.h"
24 #include "sella/util/Log.h"
25 #include "sella/util/String.h"
26 #include "sella/util/CommandLine.h"
27 #include "sella/net/IPAddressPort.h"
28 #include "sella/net/SocketMux.h"
29 #include "sella/net/SecureTCPSocket.h"
30 
31 namespace sella {
32  namespace secure {
33  bool running = true;
34  int debug = 0;
35  }
36 }
37 
38 using namespace sella::secure;
39 using namespace sella::util;
40 using namespace sella::net;
41 
42 bool init_config(int argc, char **argv);
43 bool init_signals(void);
44 void sighandler(int sig);
45 
46 int main(int argc, char **argv) {
47  SET_FORMAT(SimpleLogFormat());
48  SET_IDENTIFIER("secure");
49  SET_OPTION(Log::WithStderrOption);
50 
51  init_config(argc, argv);
52  init_signals();
53 
54  INFO("Using %s v%s", libutilxx__package(), libutilxx__version());
55 
56  try {
57  INFO("Connecting to server...");
58 
59  SecureTCPSocket::shared client = SecureTCPSocket::shared_ptr(AF_INET, "127.0.0.1", 9876);
60  client->setBlock(false);
61 
62  INFO("Using %s", client->getSSLLibraryVersion());
63  INFO("Established connection to %s with protocol %s and cipher %s", client->getRemoteIPAddressPort().c_str(), client->getActiveProtocol(), client->getActiveCipher());
64 
65  SocketMux mux;
66 
67  mux.insertRead(client);
68 
69  while (running && client->isUsable()) {
70  std::string buf = su::String::random(64);
71 
72  INFO("Send: %s", buf.c_str());
73  client->send(buf);
74 
75  if (mux.rselect(750000) > 0) { /* Client must read from socket to be able to receive a shutdown notification. */
76  std::string buf;
77  size_t n;
78 
79  if ((n = client->recv(buf)) > 0) {
80  INFO("Recv: %s", buf.c_str());
81  }
82  }
83  }
84  } catch (SocketException &e) {
85  INFO("Exception: %s", e.what());
86 
87  return EXIT_FAILURE;
88  }
89 
90  INFO("Clean shutdown");
91 
92  return EXIT_SUCCESS;
93 }
94 
95 bool init_config(int argc, char **argv) {
96  std::string m;
97  sella::util::CommandLine cmdln(argc, argv);
98 
99  cmdln.add('d', "debug", "set debug level to INT", "INT", debug, 0, 9);
100  cmdln.add();
101  cmdln.add('h', "help", "display this help screen");
102  cmdln.add('v', "version", "display version information");
103 
104  std::map<std::string, std::string> conf = cmdln.parse(stdin);
105 
106  if (conf.find("help") != conf.end()) {
107  printf("%s v%s\n", libutilxx__package(), libutilxx__version());
108  cmdln.usage(stdout, EXIT_SUCCESS);
109  } else if (conf.find("version") != conf.end()) {
110  printf("%s v%s\n", libutilxx__package(), libutilxx__version());
111 
112  exit(EXIT_SUCCESS);
113  }
114 
115  if (conf.find("debug") != conf.end()) {
116  debug = atoi(conf["debug"].c_str());
117 
118  switch (debug) {
119  case 9:
120  SET_TRACE("all");
121  SET_LOGMASK(LOG_UPTO(LOG_DEBUG));
122 
123  case 3:
124  SET_TRACE(PACKAGE "-detail");
125 
126  case 2:
127  SET_TRACE(PACKAGE);
128 
129  case 1:
130  SET_TRACE("print");
131  }
132  }
133 
134  return true;
135 }
136 
137 bool init_signals(void) {
138  struct sigaction act, old;
139 
140  act.sa_handler = sighandler;
141  sigemptyset(&act.sa_mask);
142  act.sa_flags = SA_RESTART;
143 
144  if (sigaction(SIGINT, NULL, &old) < 0) {
145  fprintf(stderr, "Failed to retrieve signal handler for SIGINT.\n");
146  } else if (old.sa_handler == SIG_DFL) {
147  if (sigaction(SIGINT, &act, NULL) < 0) {
148  fprintf(stderr, "Failed to install signal handler for SIGINT.\n");
149  }
150  }
151 
152  if (sigaction(SIGTERM, NULL, &old) < 0) {
153  fprintf(stderr, "Failed to retrieve signal handler for SIGTERM.\n");
154  } else if (old.sa_handler == SIG_DFL) {
155  if (sigaction(SIGTERM, &act, NULL) < 0) {
156  fprintf(stderr, "Failed to install signal handler for SIGTERM.\n");
157  }
158  }
159 
160  if (sigaction(SIGHUP, NULL, &old) < 0) {
161  fprintf(stderr, "Failed to retrieve signal handler for SIGHUP.\n");
162  } else if (old.sa_handler == SIG_DFL) {
163  if (sigaction(SIGHUP, &act, NULL) < 0) {
164  fprintf(stderr, "Failed to install signal handler for SIGHUP.\n");
165  }
166  }
167 
168  if (sigaction(SIGUSR1, NULL, &old) < 0) {
169  fprintf(stderr, "Failed to retrieve signal handler for SIGUSR1.\n");
170  } else if (old.sa_handler == SIG_DFL) {
171  if (sigaction(SIGUSR1, &act, NULL) < 0) {
172  fprintf(stderr, "Failed to install signal handler for SIGUSR1.\n");
173  }
174  }
175 
176  if (sigaction(SIGUSR2, NULL, &old) < 0) {
177  fprintf(stderr, "Failed to retrieve signal handler for SIGUSR2.\n");
178  } else if (old.sa_handler == SIG_DFL) {
179  if (sigaction(SIGUSR2, &act, NULL) < 0) {
180  fprintf(stderr, "Failed to install signal handler for SIGUSR2.\n");
181  }
182  }
183 
184  if (sigaction(SIGPIPE, NULL, &old) < 0) { /* Prevents send() and write() on broken socket from terminating. */
185  fprintf(stderr, "Failed to retrieve signal handler for SIGPIPE.\n");
186  } else if (old.sa_handler == SIG_DFL) {
187  if (sigaction(SIGPIPE, &act, NULL) < 0) {
188  fprintf(stderr, "Failed to install signal handler for SIGPIPE.\n");
189  }
190  }
191 
192  return true;
193 }
194 
195 void sighandler(int sig) { /* Do not call syslog within handler. Will cause hangs/crash. */
196  switch (sig) {
197  case SIGINT:
198  case SIGTERM:
199  running = false;
200 
201  break;
202 
203  case SIGHUP:
204  running = false;
205 
206  break;
207 
208  case SIGUSR1:
209  break;
210 
211  case SIGUSR2:
212  break;
213 
214  case SIGPIPE:
215  break;
216 
217  default:
218  break;
219  }
220 }
221 
222 /*
223 ** vim: noet ts=3 sw=3
224 */