My Project
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros
read_msu.c
Go to the documentation of this file.
1 /*
2 START OF LICENSE STUB
3  DeDOS: Declarative Dispersion-Oriented Software
4  Copyright (C) 2017 University of Pennsylvania, Georgetown University
5 
6  This program is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program. If not, see <http://www.gnu.org/licenses/>.
18 END OF LICENSE STUB
19 */
20 #include "webserver/read_msu.h"
21 #include "webserver/http_msu.h"
22 #include "webserver/sslops.h"
23 #include "socket_msu.h"
25 #include "routing_strategies.h"
26 #include "logging.h"
27 #include "msu_state.h"
28 #include "local_msu.h"
29 #include "msu_message.h"
30 #include "routing.h"
31 #include "local_files.h"
32 #include "msu_calls.h"
33 #include "unused_def.h"
34 
35 #include <signal.h>
36 
37 struct ws_read_state {
38  int use_ssl;
39 };
40 
41 static int handle_read(struct read_state *read_state,
42  struct ws_read_state *msu_state,
43  struct local_msu *self,
44  struct msu_msg *msg) {
45  log(LOG_WEBSERVER_READ, "Attempting read from %p", read_state);
46  int rtn = read_request(read_state);
48  read_state->conn.status = CON_READING;
49  log(LOG_WEBSERVER_READ, "Read incomplete. Re-enabling (fd: %d)", read_state->conn.fd);
50  msu_monitor_fd(read_state->conn.fd, RTN_TO_EVT(rtn), self, &msg->hdr);
51  free(msg->data);
52  return 0;
53  } else if (rtn & WS_ERROR) {
54  struct connection conn = read_state->conn;
55  msu_free_state(self, &msg->hdr.key);
56  log(LOG_WEBSERVER_READ, "Error when reading from socket!");
57  msu_error(self, &msg->hdr, 1);
58  log(LOG_WEBSERVER_READ, "Error when reading from socket!");
60  log(LOG_WEBSERVER_READ, "Error when reading from socket!");
61  close_connection(&conn);
62  return 0;
63  } else {
64  log(LOG_WEBSERVER_READ, "Read %s", read_state->req);
65  }
66  struct read_state *out = malloc(sizeof(*out));
67  memcpy(out, read_state, sizeof(*read_state));
68  msu_free_state(self, &msg->hdr.key);
69  free(msg->data);
70  call_msu_type(self, &WEBSERVER_HTTP_MSU_TYPE, &msg->hdr, sizeof(*out), out);
71  return 0;
72 }
73 
74 static int handle_accept(struct read_state *read_state,
75  struct ws_read_state *msu_state,
76  struct local_msu *self,
77  struct msu_msg *msg) {
78  int rtn = accept_connection(&read_state->conn, msu_state->use_ssl);
79  if (rtn & WS_COMPLETE) {
80  rtn = handle_read(read_state, msu_state, self, msg);
81  return rtn;
82  } else if (rtn & WS_ERROR) {
83  msu_error(self, NULL, 0);
84  msu_remove_fd_monitor(read_state->conn.fd);
85  close_connection(&read_state->conn);
86  msu_free_state(self, &msg->hdr.key);
87  free(msg->data);
88  return -1;
89  } else {
90  read_state->conn.status = CON_SSL_CONNECTING;
91  return msu_monitor_fd(read_state->conn.fd, RTN_TO_EVT(rtn), self, &msg->hdr);
92  }
93 }
94 
95 static int read_http_request(struct local_msu *self,
96  struct msu_msg *msg) {
97  struct ws_read_state *msu_state = self->msu_state;
98 
99  struct connection conn_in;
100  int sender_type_id = msu_msg_sender_type(&msg->hdr.provinance);
101  switch (sender_type_id) {
102  case SOCKET_MSU_TYPE_ID:;
103  struct socket_msg *msg_in = msg->data;
104  init_connection(&conn_in, msg_in->fd);
105  break;
107  log(LOG_WEBSERVER_READ, "Got back read msg %u", msg->hdr.key.id);
108  conn_in = *(struct connection*)msg->data;
109  break;
110  default:
111  log_error("Unknown sender MSU type ID: %d", sender_type_id);
112  return -1;
113  }
114 
115  size_t size = -1;
116  struct read_state *read_state = msu_get_state(self, &msg->hdr.key, &size);
117  if (read_state == NULL) {
118  read_state = msu_init_state(self, &msg->hdr.key, sizeof(*read_state));
119  init_read_state(read_state, &conn_in);
120  } else {
121  log(LOG_WEBSERVER_READ, "Retrieved read ptr %p", read_state);
122  }
123  if (read_state->conn.fd != conn_in.fd) {
124  log_error("Got non-matching FDs! state: %d vs input: %d", read_state->conn.fd, conn_in.fd);
125  return -1;
126  }
127 
128  switch (read_state->conn.status) {
129  case NIL:
130  case NO_CONNECTION:
131  case CON_ACCEPTED:
132  case CON_SSL_CONNECTING:
133  return handle_accept(read_state, msu_state, self, msg);
134  case CON_READING:
135  // TODO: I think it may never get here...
136  return handle_read(read_state, msu_state, self, msg);
137  default:
138  log_error("Received unknown packet status: %d", read_state->conn.status);
139  return -1;
140  }
141 }
142 
143 #define SSL_INIT_CMD "SSL"
144 
145 static int ws_read_init(struct local_msu *self, struct msu_init_data *data) {
146  struct ws_read_state *ws_state = malloc(sizeof(*ws_state));
147 
148  char *init_cmd = data->init_data;
149 
150  if (init_cmd == NULL) {
151  log_info("Initializing NON-SSL webserver-reading MSU");
152  ws_state->use_ssl = 0;
153  }
154  if (strncasecmp(init_cmd, SSL_INIT_CMD, sizeof(SSL_INIT_CMD)) == 0) {
155  log_info("Initializing SSL webserver-reading MSU");
156  ws_state->use_ssl = 1;
157  } else {
158  log_info("Initializing SSL webserver-reading MSU anyway");
159  ws_state->use_ssl = 1;
160  }
161 
162  self->msu_state = (void*)ws_state;
163  return 0;
164 }
165 
166 static void ws_read_destroy(struct local_msu *self) {
167  free(self->msu_state);
168 }
169 
170 
171 static int init_ssl_ctx(struct msu_type UNUSED *type) {
172  init_ssl_locks();
173  if (init_ssl_context() != 0) {
174  log_critical("Error intiializing SSL context");
175  return -1;
176  }
177 
178  char pem_file[256];
179  get_local_file(pem_file, "mycert.pem");
180  if (load_ssl_certificate(pem_file, pem_file) != 0) {
181  log_error("Error loading SSL cert %s", pem_file);
182  return -1;
183  }
184 
185  signal(SIGPIPE, SIG_IGN);
186 
187  return 0;
188 }
189 
190 static void destroy_ssl_ctx(struct msu_type UNUSED *type) {
191  kill_ssl_locks();
192 }
193 
195  .name = "Webserver_read_MSU",
197  .init_type = init_ssl_ctx,
198  .destroy_type = destroy_ssl_ctx,
199  .init = ws_read_init,
200  .destroy = ws_read_destroy,
201  .route = route_to_origin_runtime,
202  .receive = read_http_request
203 };
void kill_ssl_locks(void)
Definition: sslops.c:122
void init_ssl_locks(void)
Definition: sslops.c:107
struct connection conn
int msu_error(struct local_msu *msu, struct msu_msg_hdr *hdr, int broadcast)
Definition: local_msu.c:353
Macro for declaring functions or variables as unused to avoid compiler warnings.
void init_connection(struct connection *conn, int fd)
#define log_info(fmt,...)
Definition: logging.h:88
int msu_remove_fd_monitor(int fd)
Definition: socket_msu.c:87
static int init_ssl_ctx(struct msu_type UNUSED *type)
Definition: read_msu.c:171
static int ws_read_init(struct local_msu *self, struct msu_init_data *data)
Definition: read_msu.c:145
void * msu_get_state(struct local_msu *msu, struct msu_msg_key *key, size_t *size)
Gets the state allocated with the given key.
Definition: msu_state.c:82
static int handle_read(struct read_state *read_state, struct ws_read_state *msu_state, struct local_msu *self, struct msu_msg *msg)
Definition: read_msu.c:41
#define log_critical(fmt,...)
Definition: logging.h:124
struct msu_type WEBSERVER_HTTP_MSU_TYPE
Definition: http_msu.c:202
unsigned int msu_msg_sender_type(struct msg_provinance *prov)
Definition: msu_message.c:41
State storage that is tied to a specific MSU mesasge.
void * data
Payload.
Definition: msu_message.h:104
int32_t id
A shorter, often hashed id for the key of fixed length (used in routing)
Definition: msu_message.h:52
#define WS_INCOMPLETE_READ
Definition: webserver.h:25
#define SOCKET_MSU_TYPE_ID
Definition: msu_ids.h:23
Logging of status messages to the terminal.
Access local files within the repo.
#define WS_INCOMPLETE_WRITE
Definition: webserver.h:26
int close_connection(struct connection *conn)
void * msu_init_state(struct local_msu *msu, struct msu_msg_key *key, size_t size)
Initializes a new MSU state of the given size with the provided key.
Definition: msu_state.c:55
static int handle_accept(struct read_state *read_state, struct ws_read_state *msu_state, struct local_msu *self, struct msu_msg *msg)
Definition: read_msu.c:74
int load_ssl_certificate(char *cert_file, char *key_file)
Definition: sslops.c:160
struct msu_type WEBSERVER_READ_MSU_TYPE
Definition: read_msu.c:194
#define SSL_INIT_CMD
Definition: read_msu.c:143
Declares the methods available for calling an MSU from another MSU.
void init_read_state(struct read_state *state, struct connection *conn)
static void ws_read_destroy(struct local_msu *self)
Definition: read_msu.c:166
struct msg_provinance provinance
Message history.
Definition: msu_message.h:89
#define log_error(fmt,...)
Definition: logging.h:101
Declares the structures and functions applicable to MSUs on the local machine.
Definition: webserver.h:30
char req[4096]
static int read_http_request(struct local_msu *self, struct msu_msg *msg)
Definition: read_msu.c:95
The structure that represents an MSU located on the local machine.
Definition: local_msu.h:38
Data with which an MSU is initialized, and the payload for messages of type CTRL_CREATE_MSU.
Definition: dfg.h:66
Functions for routing MSU messages between MSUs.
int get_local_file(char *out, char *file)
Gets a file relative to the path of the executable.
Definition: local_files.c:38
#define UNUSED
The structure contining msu state.
Definition: msu_state.c:35
int call_msu_type(struct local_msu *sender, struct msu_type *dst_type, struct msu_msg_hdr *hdr, size_t data_size, void *data)
Sends an MSU message to a destination of the given type, utilizing the sending MSU's routing function...
Definition: msu_calls.c:146
Defines a type of MSU.
Definition: msu_type.h:46
#define WEBSERVER_READ_MSU_TYPE_ID
Definition: msu_ids.h:25
int init_ssl_context(void)
Definition: sslops.c:134
#define RTN_TO_EVT(rtn__)
Definition: webserver.h:40
static int accept_connection(int fd, void *data)
Accepts a new connection.
struct msu_msg_hdr hdr
Definition: msu_message.h:102
#define WS_COMPLETE
Definition: webserver.h:24
#define WS_ERROR
Definition: webserver.h:27
#define WEBSERVER_HTTP_MSU_TYPE_ID
Definition: msu_ids.h:26
char init_data[64]
Definition: dfg.h:67
int msu_monitor_fd(int fd, uint32_t events, struct local_msu *destination, struct msu_msg_hdr *hdr)
Definition: socket_msu.c:58
#define log(level, fmt,...)
Log at a custom level.
Definition: logging.h:147
A message that is to be delivered to an instance of an MSU.
Definition: msu_message.h:101
Messages passed to MSUs.
int read_request(struct read_state *state)
int msu_free_state(struct local_msu *msu, struct msu_msg_key *key)
Frees the state assocated with the given MSU and key.
Definition: msu_state.c:97
char * name
Name for the msu type.
Definition: msu_type.h:48
int route_to_origin_runtime(struct msu_type *type, struct local_msu *sender, struct msu_msg *msg, struct msu_endpoint *output)
Routes an MSU message to the runtime on which the message originated.
static void destroy_ssl_ctx(struct msu_type UNUSED *type)
Definition: read_msu.c:190
Declares strategies that MSUs can use for routing to endpoints.
struct msu_msg_key key
Routing/state key.
Definition: msu_message.h:87
enum webserver_status status