My Project
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros
socketops.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/socketops.h"
21 #include "webserver/webserver.h"
22 #include <unistd.h>
23 #include "logging.h"
24 #include <netinet/ip.h>
25 
26 
28  .domain = AF_INET,
29  .type = SOCK_STREAM,
30  .protocol = 0,
31  .bind_ip = INADDR_ANY,
32  .reuse_addr = 1,
33  .reuse_port = 1
34 };
35 
37  ws_sock_settings.port = port;
38  return &ws_sock_settings;
39 }
40 
41 #define SOCKET_BACKLOG 512
42 
43 int init_socket(struct sock_settings *settings) {
44 
45  int socket_fd = socket(
46  settings->domain,
47  settings->type,
48  settings->protocol);
49 
50  if ( socket_fd == -1 ) {
51  log_perror("socket() failed");
52  return -1;
53  }
54 
55  int opt = settings->reuse_addr;
56  if (setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1) {
57  log_perror("setsockopt() failed for reuseaddr");
58  }
59  opt = settings->reuse_port;
60  if (setsockopt(socket_fd, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(&opt)) == -1) {
61  log_perror("setsockopt() failed for reuseport");
62  }
63 
64  struct sockaddr_in addr;
65  addr.sin_family = settings->domain;
66  addr.sin_addr.s_addr = settings->bind_ip;
67  addr.sin_port = htons(settings->port);
68 
69  if (bind(socket_fd, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
70  log_perror("bind() failed");
71  close(socket_fd);
72  return -1;
73  }
74 
75  if (listen(socket_fd, SOCKET_BACKLOG) == -1) {
76  log_perror("listen() failed");
77  close(socket_fd);
78  return -1;
79  }
80 
81  return socket_fd;
82 }
83 
84 int read_socket(int fd, char *buf, int *buf_size) {
85  int num_bytes = read(fd, buf, *buf_size);
86  if (num_bytes >= 0) {
87  *buf_size = num_bytes;
88  return WS_COMPLETE;
89  } else {
90  if (errno == EAGAIN) {
91  return WS_INCOMPLETE_READ;
92  } else {
93  log_perror("Error reading from socket %d", fd);
94  return WS_ERROR;
95  }
96  }
97 }
98 
99 int write_socket(int fd, char *buf, int *buf_size) {
100  int num_bytes = write(fd, buf, *buf_size);
101  if (num_bytes > 0) {
102  if (num_bytes != *buf_size) {
103  log_warn("Didn't write the right number of bytes?");
104  }
105  *buf_size = num_bytes;
106  return WS_COMPLETE;
107  } else {
108  if (errno == EAGAIN) {
109  return WS_INCOMPLETE_WRITE;
110  } else {
111  log_perror("Error writing to socket %d (rtn: %d, requested: %d)",
112  fd, num_bytes, *buf_size);
113  return WS_ERROR;
114  }
115  }
116 }
int write_socket(int fd, char *buf, int *buf_size)
Definition: socketops.c:99
#define WS_INCOMPLETE_READ
Definition: webserver.h:25
#define log_perror(fmt,...)
Definition: logging.h:102
Logging of status messages to the terminal.
int reuse_port
Definition: socketops.h:30
#define WS_INCOMPLETE_WRITE
Definition: webserver.h:26
int init_socket(struct sock_settings *settings)
Definition: socketops.c:43
static struct sock_settings ws_sock_settings
Definition: socketops.c:27
#define SOCKET_BACKLOG
Definition: socketops.c:41
int read_socket(int fd, char *buf, int *buf_size)
Definition: socketops.c:84
int reuse_addr
Definition: socketops.h:29
struct sock_settings * webserver_sock_settings(int port)
Definition: socketops.c:36
#define WS_COMPLETE
Definition: webserver.h:24
#define WS_ERROR
Definition: webserver.h:27
unsigned long bind_ip
Definition: socketops.h:28
#define log_warn(fmt,...)
Definition: logging.h:113