Bredbandskollen CLI  1.2
Asynchronous network task engine
engine.h
1 // Copyright (c) 2018 IIS (The Internet Foundation in Sweden)
2 // Written by Göran Andersson <initgoran@gmail.com>
3 
4 // This class implements a network engine, managing sockets.
5 // It is only used by the EventLoop class.
6 
7 #pragma once
8 
9 #include <thread>
10 #include <map>
11 #include <vector>
12 #include <string>
13 
14 #include "logger.h"
15 
16 #ifdef _WIN32
17 #include <winsock2.h>
18 #endif
19 
20 class Socket;
21 class SocketConnection;
22 class ServerSocket;
23 class Task;
24 
25 #ifdef USE_GNUTLS
26 #include <gnutls/gnutls.h>
27 #endif
28 
33 class Engine : public Logger {
34 public:
35  bool addClient(SocketConnection *conn);
36  void addConnected(SocketConnection *conn);
37  bool addServer(ServerSocket *conn);
38 
39  Engine(std::string label);
40 
42  ~Engine();
43 
47  void terminate(unsigned int max_time_ms);
48 
51 
61  bool run(double max_time);
62 
64  void deleteConnByTask(const Task *task);
65 
67  static void yield() {
68  yield_called = true;
69  }
70 
74  static void notifyOutOfFds() {
75  // TODO: thread safe
76  max_open_fd_reached = true;
77  }
78  std::set<Socket *> findSockByTask(const Task *t) const;
79 
81  void wakeUpByTask(Task *t);
82 
85  void cancelConnection(SocketConnection *s);
86 
89  bool connActive(const Socket *conn) const {
90  for (auto it : connectionStore)
91  if (it.second == conn)
92  return true;
93  return false;
94  }
95 
97  void resetDeadline(const TimePoint &t) {
98  if (deadline > t)
99  deadline = t;
100  }
101 
102 #ifdef USE_GNUTLS
104  bool setCABundle(const std::string &path);
105 
107  bool tlsSetKey(ServerSocket *conn, const std::string &crt_path,
108  const std::string &key_path, const std::string &password);
109 #endif
110 
111 private:
112 
113  TimePoint deadline;
114 #ifdef USE_THREADS
115  thread_local
116 #endif
117  static volatile bool yield_called;
118  static bool max_open_fd_reached;
119  void handleMaxOpenFdReached();
120  void killConnection(int fd);
121  void handleIncoming(ServerSocket *server);
122  // Check all connections, remove closed, reclaim keepalive,
123  // return false if none was removed:
124  bool reclaimConnections();
125 
126  // Prepare for select, return largest fd or -1:
127  int setFds(fd_set &r, fd_set &w, fd_set &e);
128  // Check error from select, return false if fatal:
129  bool fatalSelectError();
130  // Take care of all network events:
131  void doFds(const fd_set &r, const fd_set &w, const fd_set &e, int max);
132 
133  // Map socket number to Socket object:
134  std::map<int, Socket *> connectionStore;
135 
136  // Cache of open connections that may be reused.
137  // Value is socket number. Key is some kind of label,
138  // chosen by the tasks owning the connections,
139  // that should identify the type of connection.
140  std::multimap<std::string, int> keepaliveCache;
141 #ifdef USE_GNUTLS
142  std::map<int, gnutls_session_t> tls_session_cache;
143  std::string ca_bundle;
144  std::map<std::string, unsigned int> tls_crt_map;
145  // Index 0 is used for outgoing connection, containing trust store.
146  // At index > 0 certificates for server sockets are stored.
147  std::vector<gnutls_certificate_credentials_t> x509_cred;
148  gnutls_priority_t priority_cache;
149 #endif
150 };
The network engine.
Definition: engine.h:33
void childProcessCloseSockets()
Call this in child process to close all redundant sockets after fork.
Definition: engine.cpp:180
bool tlsSetKey(ServerSocket *conn, const std::string &crt_path, const std::string &key_path, const std::string &password)
Use SSL certificate for a listening socket.
Definition: engine.cpp:73
void terminate(unsigned int max_time_ms)
Definition: engine.cpp:187
bool connActive(const Socket *conn) const
Definition: engine.h:89
void resetDeadline(const TimePoint &t)
Call this to make the Engine::run method return earlier.
Definition: engine.h:97
bool wakeUpConnection(SocketConnection *s)
Wake up connection s if it is idle, return false otherwise.
Definition: engine.cpp:587
~Engine()
Will kill all remaining connections.
Definition: engine.cpp:47
void deleteConnByTask(const Task *task)
Remove all connections owned by the task.
Definition: engine.cpp:594
bool setCABundle(const std::string &path)
Set path to file containing chain of trust for SSL certificate.
Definition: engine.cpp:63
static void yield()
Call this to make the Engine::run method return prematurely.
Definition: engine.h:67
static void notifyOutOfFds()
Call this to enter a recovery mode if no more file descriptors could be created.
Definition: engine.h:74
bool run(double max_time)
Run the "event loop" for at most max_time seconds.
Definition: engine.cpp:334
void wakeUpByTask(Task *t)
Wake up all idle connections belonging to t:
Definition: engine.cpp:580
A simple logger. All classes that want to write to the global log file should inherit from this class...
Definition: logger.h:86
std::string label() const
Return the object's log label.
Definition: logger.h:251
Listen on a single socket for incoming connections.
Definition: serversocket.h:15
This class implements low-level socket connection operations. Inherit from it to implement protocols ...
Definition: socketconnection.h:47
This is a slave to the Engine class. You can't use it directly, only through its subclasses,...
Definition: socket.h:18
The purpose of a task is to manage socket connections, and/or to execute timers.
Definition: task.h:39
Measure elapsed time during execution, for example by timer events.