LCOV - code coverage report
Current view: top level - msus/webserver - read_msu.c (source / functions) Hit Total Coverage
Test: unnamed Lines: 78 96 81.2 %
Date: 2018-01-11 Functions: 7 7 100.0 %

          Line data    Source code
       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"
      24             : #include "webserver/connection-handler.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         296 : 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         296 :     log(LOG_WEBSERVER_READ, "Attempting read from %p", read_state);
      46         296 :     int rtn = read_request(read_state);
      47         296 :     if (rtn & (WS_INCOMPLETE_WRITE | WS_INCOMPLETE_READ)) {
      48         149 :         read_state->conn.status = CON_READING;
      49         149 :         log(LOG_WEBSERVER_READ, "Read incomplete. Re-enabling (fd: %d)", read_state->conn.fd);
      50         149 :         msu_monitor_fd(read_state->conn.fd, RTN_TO_EVT(rtn), self, &msg->hdr);
      51         149 :         free(msg->data);
      52         149 :         return 0;
      53         147 :     } else if (rtn & WS_ERROR) {
      54           1 :         struct connection conn = read_state->conn;
      55           1 :         msu_free_state(self, &msg->hdr.key);
      56           1 :         log(LOG_WEBSERVER_READ, "Error when reading from socket!");
      57           1 :         msu_error(self, &msg->hdr, 1);
      58           1 :         log(LOG_WEBSERVER_READ, "Error when reading from socket!");
      59           1 :         msu_remove_fd_monitor(conn.fd);
      60           1 :         log(LOG_WEBSERVER_READ, "Error when reading from socket!");
      61           1 :         close_connection(&conn);
      62           1 :         return 0;
      63             :     } else {
      64         146 :         log(LOG_WEBSERVER_READ, "Read %s", read_state->req);
      65             :     }
      66         146 :     struct read_state *out = malloc(sizeof(*out));
      67         146 :     memcpy(out, read_state, sizeof(*read_state));
      68         146 :     msu_free_state(self, &msg->hdr.key);
      69         146 :     free(msg->data);
      70         146 :     call_msu_type(self, &WEBSERVER_HTTP_MSU_TYPE, &msg->hdr, sizeof(*out), out);
      71         146 :     return 0;
      72             : }
      73             : 
      74         296 : 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         296 :     int rtn = accept_connection(&read_state->conn, msu_state->use_ssl);
      79         296 :     if (rtn & WS_COMPLETE) {
      80         148 :         rtn = handle_read(read_state, msu_state, self, msg);
      81         148 :         return rtn;
      82         148 :     } else if (rtn & WS_ERROR) {
      83           0 :         msu_error(self, NULL, 0);
      84           0 :         msu_remove_fd_monitor(read_state->conn.fd);
      85           0 :         close_connection(&read_state->conn);
      86           0 :         msu_free_state(self, &msg->hdr.key);
      87           0 :         free(msg->data);
      88           0 :         return -1;
      89             :     } else {
      90         148 :         read_state->conn.status = CON_SSL_CONNECTING;
      91         148 :         return msu_monitor_fd(read_state->conn.fd, RTN_TO_EVT(rtn), self, &msg->hdr);
      92             :     }
      93             : }
      94             : 
      95         444 : static int read_http_request(struct local_msu *self,
      96             :                              struct msu_msg *msg) {
      97         444 :     struct ws_read_state *msu_state = self->msu_state;
      98             : 
      99             :     struct connection conn_in;
     100         444 :     int sender_type_id = msu_msg_sender_type(&msg->hdr.provinance);
     101         444 :     switch (sender_type_id) {
     102             :         case SOCKET_MSU_TYPE_ID:;
     103         441 :             struct socket_msg *msg_in = msg->data;
     104         441 :             init_connection(&conn_in, msg_in->fd);
     105         441 :             break;
     106             :         case WEBSERVER_HTTP_MSU_TYPE_ID:
     107           3 :             log(LOG_WEBSERVER_READ, "Got back read msg %u", msg->hdr.key.id);
     108           3 :             conn_in = *(struct connection*)msg->data;
     109           3 :             break;
     110             :         default:
     111           0 :             log_error("Unknown sender MSU type ID: %d", sender_type_id);
     112           0 :             return -1;
     113             :     }
     114             : 
     115         444 :     size_t size = -1;
     116         444 :     struct read_state *read_state = msu_get_state(self, &msg->hdr.key, &size);
     117         444 :     if (read_state == NULL) {
     118         153 :         read_state = msu_init_state(self, &msg->hdr.key, sizeof(*read_state));
     119         153 :         init_read_state(read_state, &conn_in);
     120             :     } else {
     121         291 :         log(LOG_WEBSERVER_READ, "Retrieved read ptr %p", read_state);
     122             :     }
     123         444 :     if (read_state->conn.fd != conn_in.fd) {
     124           0 :         log_error("Got non-matching FDs! state: %d vs input: %d", read_state->conn.fd, conn_in.fd);
     125           0 :         return -1;
     126             :     }
     127             : 
     128         444 :     switch (read_state->conn.status) {
     129             :         case NIL:
     130             :         case NO_CONNECTION:
     131             :         case CON_ACCEPTED:
     132             :         case CON_SSL_CONNECTING:
     133         296 :             return handle_accept(read_state, msu_state, self, msg);
     134             :         case CON_READING:
     135             :             // TODO: I think it may never get here...
     136         148 :             return handle_read(read_state, msu_state, self, msg);
     137             :         default:
     138           0 :             log_error("Received unknown packet status: %d", read_state->conn.status);
     139           0 :             return -1;
     140             :     }
     141             : }
     142             : 
     143             : #define SSL_INIT_CMD "SSL"
     144             : 
     145          41 : static int ws_read_init(struct local_msu *self, struct msu_init_data *data) {
     146          41 :     struct ws_read_state *ws_state = malloc(sizeof(*ws_state));
     147             : 
     148          41 :     char *init_cmd = data->init_data;
     149             : 
     150          41 :     if (init_cmd == NULL) {
     151           0 :         log_info("Initializing NON-SSL webserver-reading MSU");
     152           0 :         ws_state->use_ssl = 0;
     153             :     }
     154          41 :     if (strncasecmp(init_cmd, SSL_INIT_CMD, sizeof(SSL_INIT_CMD)) == 0) {
     155          13 :         log_info("Initializing SSL webserver-reading MSU");
     156          13 :         ws_state->use_ssl = 1;
     157             :     } else {
     158          28 :         log_info("Initializing SSL webserver-reading MSU anyway");
     159          28 :         ws_state->use_ssl = 1;
     160             :     }
     161             : 
     162          41 :     self->msu_state = (void*)ws_state;
     163          41 :     return 0;
     164             : }
     165             : 
     166          36 : static void ws_read_destroy(struct local_msu *self) {
     167          36 :     free(self->msu_state);
     168          36 : }
     169             : 
     170             : 
     171          40 : static int init_ssl_ctx(struct msu_type UNUSED *type) {
     172          40 :     init_ssl_locks();
     173          40 :     if (init_ssl_context() != 0) {
     174           0 :         log_critical("Error intiializing SSL context");
     175           0 :         return -1;
     176             :     }
     177             : 
     178             :     char pem_file[256];
     179          40 :     get_local_file(pem_file, "mycert.pem");
     180          40 :     if (load_ssl_certificate(pem_file, pem_file) != 0) {
     181           0 :         log_error("Error loading SSL cert %s", pem_file);
     182           0 :         return -1;
     183             :     }
     184             : 
     185          40 :     signal(SIGPIPE, SIG_IGN);
     186             : 
     187          40 :     return 0;
     188             : }
     189             : 
     190          35 : static void destroy_ssl_ctx(struct msu_type UNUSED *type) {
     191          35 :     kill_ssl_locks();
     192          35 : }
     193             : 
     194             : struct msu_type WEBSERVER_READ_MSU_TYPE = {
     195             :     .name = "Webserver_read_MSU",
     196             :     .id = WEBSERVER_READ_MSU_TYPE_ID,
     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             : };

Generated by: LCOV version 1.10