Fix more compilation errors

This commit is contained in:
2025-11-21 15:12:32 +01:00
parent 93ccb5d6a1
commit aab1b8e7b8
10 changed files with 1892 additions and 1763 deletions
+1 -1
View File
@@ -6,7 +6,7 @@ chttp.c chttp.h: $(wildcard src/*.c src/*.h) misc/amalg.py Makefile
python misc/amalg.py python misc/amalg.py
example: main.c chttp.c chttp.h example: main.c chttp.c chttp.h
gcc main.c chttp.c -o example.exe gcc main.c chttp.c -o example.exe -Wfatal-errors
clean: clean:
rm chttp.c chttp.h rm chttp.c chttp.h
+1609 -1562
View File
File diff suppressed because it is too large Load Diff
+133 -115
View File
@@ -17,12 +17,14 @@
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
#include <windows.h> #include <windows.h>
#include <winsock2.h> #include <winsock2.h>
#include <ws2tcpip.h>
#else #else
#include <unistd.h> #include <unistd.h>
#include <pthread.h> #include <pthread.h>
#include <poll.h> #include <poll.h>
#include <fcntl.h> #include <fcntl.h>
#include <errno.h> #include <errno.h>
#include <netdb.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <sys/socket.h> #include <sys/socket.h>
@@ -82,6 +84,120 @@ void print_bytes(HTTP_String prefix, HTTP_String src);
// TODO: comment // TODO: comment
#define HTTP_UNPACK(X) (X).len, (X).ptr #define HTTP_UNPACK(X) (X).len, (X).ptr
////////////////////////////////////////////////////////////////////////////////////////
// src/parse.h
////////////////////////////////////////////////////////////////////////////////////////
#define HTTP_MAX_HEADERS 32
typedef struct {
unsigned int data;
} HTTP_IPv4;
typedef struct {
unsigned short data[8];
} HTTP_IPv6;
typedef enum {
HTTP_HOST_MODE_VOID = 0,
HTTP_HOST_MODE_NAME,
HTTP_HOST_MODE_IPV4,
HTTP_HOST_MODE_IPV6,
} HTTP_HostMode;
typedef struct {
HTTP_HostMode mode;
HTTP_String text;
union {
HTTP_String name;
HTTP_IPv4 ipv4;
HTTP_IPv6 ipv6;
};
} HTTP_Host;
typedef struct {
HTTP_String userinfo;
HTTP_Host host;
int port;
} HTTP_Authority;
// ZII
typedef struct {
HTTP_String scheme;
HTTP_Authority authority;
HTTP_String path;
HTTP_String query;
HTTP_String fragment;
} HTTP_URL;
typedef enum {
HTTP_METHOD_GET,
HTTP_METHOD_HEAD,
HTTP_METHOD_POST,
HTTP_METHOD_PUT,
HTTP_METHOD_DELETE,
HTTP_METHOD_CONNECT,
HTTP_METHOD_OPTIONS,
HTTP_METHOD_TRACE,
HTTP_METHOD_PATCH,
} HTTP_Method;
typedef struct {
HTTP_String name;
HTTP_String value;
} HTTP_Header;
typedef struct {
bool secure;
HTTP_Method method;
HTTP_URL url;
int minor;
int num_headers;
HTTP_Header headers[HTTP_MAX_HEADERS];
HTTP_String body;
} HTTP_Request;
typedef struct {
void* context;
int minor;
int status;
HTTP_String reason;
int num_headers;
HTTP_Header headers[HTTP_MAX_HEADERS];
HTTP_String body;
} HTTP_Response;
int http_parse_ipv4 (char *src, int len, HTTP_IPv4 *ipv4);
int http_parse_ipv6 (char *src, int len, HTTP_IPv6 *ipv6);
int http_parse_url (char *src, int len, HTTP_URL *url);
int http_parse_request (char *src, int len, HTTP_Request *req);
int http_parse_response (char *src, int len, HTTP_Response *res);
int http_find_header (HTTP_Header *headers, int num_headers, HTTP_String name);
HTTP_String http_get_cookie (HTTP_Request *req, HTTP_String name);
HTTP_String http_get_param (HTTP_String body, HTTP_String str, char *mem, int cap);
int http_get_param_i (HTTP_String body, HTTP_String str);
// Checks whether the request was meant for the host with the given
// domain an port. If port is -1, the default value of 80 is assumed.
bool http_match_host(HTTP_Request *req, HTTP_String domain, int port);
////////////////////////////////////////////////////////////////////////////////////////
// src/thread.h
////////////////////////////////////////////////////////////////////////////////////////
#ifdef _WIN32
typedef CRITICAL_SECTION Mutex;
#else
typedef pthread_mutex_t Mutex;
#endif
int mutex_init(Mutex *mutex);
int mutex_free(Mutex *mutex);
int mutex_lock(Mutex *mutex);
int mutex_unlock(Mutex *mutex);
//////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////
// src/secure_context.h // src/secure_context.h
//////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////
@@ -222,10 +338,14 @@ typedef enum {
// still pending. // still pending.
SOCKET_STATE_CONNECTING, SOCKET_STATE_CONNECTING,
// The connection was estabished, but a TLS // Outgoing connection was established, but
// handshake may need to be performed. // a TLS handshake may need to be performed.
SOCKET_STATE_CONNECTED, SOCKET_STATE_CONNECTED,
// Incoming connection was established, but
// a TLS handshake may need to be performed.
SOCKET_STATE_ACCEPTED,
// The connection was esablished, but the user // The connection was esablished, but the user
// wants to perform a read or write operation that // wants to perform a read or write operation that
// would block. // would block.
@@ -419,20 +539,7 @@ void socket_close(SocketManager *sm, SocketHandle handle);
int socket_is_secure(SocketManager *sm, SocketHandle handle); int socket_is_secure(SocketManager *sm, SocketHandle handle);
// Set the user pointer of a socket // Set the user pointer of a socket
void socket_set_user(SocketManager *sm, SocketHandle handle); void socket_set_user(SocketManager *sm, SocketHandle handle, void *user);
////////////////////////////////////////////////////////////////////////////////////////
// src/thread.h
////////////////////////////////////////////////////////////////////////////////////////
typedef struct {
char unused; // TODO
} Mutex;
int mutex_init(Mutex *mutex);
int mutex_free(Mutex *mutex);
int mutex_lock(Mutex *mutex);
int mutex_unlock(Mutex *mutex);
//////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////
// src/byte_queue.h // src/byte_queue.h
@@ -714,105 +821,6 @@ bool http_client_next_response(HTTP_Client *client,
// again after this. // again after this.
void http_free_response(HTTP_Response *res); void http_free_response(HTTP_Response *res);
////////////////////////////////////////////////////////////////////////////////////////
// src/parse.h
////////////////////////////////////////////////////////////////////////////////////////
#define HTTP_MAX_HEADERS 32
typedef struct {
unsigned int data;
} HTTP_IPv4;
typedef struct {
unsigned short data[8];
} HTTP_IPv6;
typedef enum {
HTTP_HOST_MODE_VOID = 0,
HTTP_HOST_MODE_NAME,
HTTP_HOST_MODE_IPV4,
HTTP_HOST_MODE_IPV6,
} HTTP_HostMode;
typedef struct {
HTTP_HostMode mode;
HTTP_String text;
union {
HTTP_String name;
HTTP_IPv4 ipv4;
HTTP_IPv6 ipv6;
};
} HTTP_Host;
typedef struct {
HTTP_String userinfo;
HTTP_Host host;
int port;
} HTTP_Authority;
// ZII
typedef struct {
HTTP_String scheme;
HTTP_Authority authority;
HTTP_String path;
HTTP_String query;
HTTP_String fragment;
} HTTP_URL;
typedef enum {
HTTP_METHOD_GET,
HTTP_METHOD_HEAD,
HTTP_METHOD_POST,
HTTP_METHOD_PUT,
HTTP_METHOD_DELETE,
HTTP_METHOD_CONNECT,
HTTP_METHOD_OPTIONS,
HTTP_METHOD_TRACE,
HTTP_METHOD_PATCH,
} HTTP_Method;
typedef struct {
HTTP_String name;
HTTP_String value;
} HTTP_Header;
typedef struct {
bool secure;
HTTP_Method method;
HTTP_URL url;
int minor;
int num_headers;
HTTP_Header headers[HTTP_MAX_HEADERS];
HTTP_String body;
} HTTP_Request;
typedef struct {
void* context;
int minor;
int status;
HTTP_String reason;
int num_headers;
HTTP_Header headers[HTTP_MAX_HEADERS];
HTTP_String body;
} HTTP_Response;
int http_parse_ipv4 (char *src, int len, HTTP_IPv4 *ipv4);
int http_parse_ipv6 (char *src, int len, HTTP_IPv6 *ipv6);
int http_parse_url (char *src, int len, HTTP_URL *url);
int http_parse_request (char *src, int len, HTTP_Request *req);
int http_parse_response (char *src, int len, HTTP_Response *res);
int http_find_header (HTTP_Header *headers, int num_headers, HTTP_String name);
HTTP_String http_get_cookie (HTTP_Request *req, HTTP_String name);
HTTP_String http_get_param (HTTP_String body, HTTP_String str, char *mem, int cap);
int http_get_param_i (HTTP_String body, HTTP_String str);
// Checks whether the request was meant for the host with the given
// domain an port. If port is -1, the default value of 80 is assumed.
bool http_match_host(HTTP_Request *req, HTTP_String domain, int port);
//////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////
// src/server.h // src/server.h
//////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////
@@ -886,6 +894,11 @@ typedef struct {
typedef struct { typedef struct {
// Size limit of the input and output buffer of each
// connection.
uint32_t input_buffer_limit;
uint32_t output_buffer_limit;
// Array of connections. The counter contains the // Array of connections. The counter contains the
// number of structs such that state=FREE. // number of structs such that state=FREE.
int num_conns; int num_conns;
@@ -923,6 +936,11 @@ int http_server_init(HTTP_Server *server);
// Release resources associated to the server. // Release resources associated to the server.
void http_server_free(HTTP_Server *server); void http_server_free(HTTP_Server *server);
// Set input and output buffer size limit for any
// given connection. The default value is 1MB
void http_server_set_input_limit(HTTP_Server *server, uint32_t limit);
void http_server_set_output_limit(HTTP_Server *server, uint32_t limit);
// Enable listening for plain HTTP requests at the // Enable listening for plain HTTP requests at the
// specified interface. // specified interface.
int http_server_listen_tcp(HTTP_Server *server, int http_server_listen_tcp(HTTP_Server *server,
+4 -4
View File
@@ -56,13 +56,13 @@ header = Amalgamator()
header.append_text(desc) header.append_text(desc)
header.append_file("src/includes.h") header.append_file("src/includes.h")
header.append_file("src/basic.h") header.append_file("src/basic.h")
header.append_file("src/parse.h")
header.append_file("src/thread.h")
header.append_file("src/secure_context.h") header.append_file("src/secure_context.h")
header.append_file("src/socket.h") header.append_file("src/socket.h")
header.append_file("src/thread.h")
header.append_file("src/byte_queue.h") header.append_file("src/byte_queue.h")
header.append_file("src/cert.h") header.append_file("src/cert.h")
header.append_file("src/client.h") header.append_file("src/client.h")
header.append_file("src/parse.h")
header.append_file("src/server.h") header.append_file("src/server.h")
header.append_text(license) header.append_text(license)
header.save("chttp.h") header.save("chttp.h")
@@ -74,13 +74,13 @@ source.append_text("#ifndef HTTP_DONT_INCLUDE\n")
source.append_text('#include "chttp.h"\n') source.append_text('#include "chttp.h"\n')
source.append_text("#endif\n") source.append_text("#endif\n")
source.append_file("src/basic.c") source.append_file("src/basic.c")
source.append_file("src/parse.c")
source.append_file("src/thread.c")
source.append_file("src/secure_context.c") source.append_file("src/secure_context.c")
source.append_file("src/socket.c") source.append_file("src/socket.c")
source.append_file("src/thread.c")
source.append_file("src/byte_queue.c") source.append_file("src/byte_queue.c")
source.append_file("src/cert.c") source.append_file("src/cert.c")
source.append_file("src/client.c") source.append_file("src/client.c")
source.append_file("src/parse.c")
source.append_file("src/server.c") source.append_file("src/server.c")
header.append_text(license) header.append_text(license)
source.save("chttp.c") source.save("chttp.c")
+1
View File
@@ -9,6 +9,7 @@
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
#include <windows.h> #include <windows.h>
#include <winsock2.h> #include <winsock2.h>
#include <ws2tcpip.h>
#else #else
#include <unistd.h> #include <unistd.h>
#include <pthread.h> #include <pthread.h>
+40 -8
View File
@@ -1,6 +1,25 @@
static void http_server_conn_init(HTTP_ServerConn *conn,
SocketHandle handle, uint32_t input_buffer_limit,
uint32_t output_buffer_limit)
{
conn->state = HTTP_SERVER_CONN_BUFFERING;
conn->handle = handle;
byte_queue_init(&conn->input, input_buffer_limit);
byte_queue_init(&conn->output, output_buffer_limit);
}
static void http_server_conn_free(HTTP_ServerConn *conn)
{
byte_queue_free(&conn->output);
byte_queue_free(&conn->input);
}
int http_server_init(HTTP_Server *server) int http_server_init(HTTP_Server *server)
{ {
server->input_buffer_limit = 1<<20;
server->output_buffer_limit = 1<<20;
server->num_conns = 0; server->num_conns = 0;
for (int i = 0; i < HTTP_SERVER_CAPACITY; i++) for (int i = 0; i < HTTP_SERVER_CAPACITY; i++)
server->conns[i].state = HTTP_SERVER_CONN_FREE; server->conns[i].state = HTTP_SERVER_CONN_FREE;
@@ -9,7 +28,7 @@ int http_server_init(HTTP_Server *server)
server->ready_head = 0; server->ready_head = 0;
if (socket_manager_init(&server->sockets, if (socket_manager_init(&server->sockets,
&server->socket_pool, HTTP_SERVER_CAPACITY) < 0) server->socket_pool, HTTP_SERVER_CAPACITY) < 0)
return -1; return -1;
return 0; return 0;
} }
@@ -28,6 +47,16 @@ void http_server_free(HTTP_Server *server)
} }
} }
void http_server_set_input_limit(HTTP_Server *server, uint32_t limit)
{
server->input_buffer_limit = limit;
}
void http_server_set_output_limit(HTTP_Server *server, uint32_t limit)
{
server->output_buffer_limit = limit;
}
int http_server_listen_tcp(HTTP_Server *server, int http_server_listen_tcp(HTTP_Server *server,
String addr, Port port) String addr, Port port)
{ {
@@ -101,7 +130,7 @@ check_request_buffer(HTTP_Server *server, HTTP_ServerConn *conn)
// Ready // Ready
assert(ret == 1); assert(ret == 1);
conn->state = HTTP_SERVER_CONN_STATUS; conn->state = HTTP_SERVER_CONN_WAIT_STATUS;
conn->request_len = ret; conn->request_len = ret;
conn->response_offset = byte_queue_offset(&conn->output); conn->response_offset = byte_queue_offset(&conn->output);
@@ -133,7 +162,7 @@ int http_server_process_events(HTTP_Server *server,
struct pollfd *polled, int num_polled) struct pollfd *polled, int num_polled)
{ {
SocketEvent events[HTTP_SERVER_CAPACITY]; SocketEvent events[HTTP_SERVER_CAPACITY];
int num_events = socket_manger_translate_events(&server->sockets, polled, num_polled); int num_events = socket_manager_translate_events(&server->sockets, polled, num_polled);
if (num_events < 0) if (num_events < 0)
return -1; return -1;
@@ -162,7 +191,10 @@ int http_server_process_events(HTTP_Server *server,
} }
conn = &server->conns[i]; conn = &server->conns[i];
http_server_conn_init(conn, events[i].handle); http_server_conn_init(conn,
events[i].handle,
server->input_buffer_limit,
server->output_buffer_limit);
server->num_conns++; server->num_conns++;
socket_set_user(&server->sockets, events[i].handle, conn); socket_set_user(&server->sockets, events[i].handle, conn);
@@ -226,11 +258,11 @@ builder_to_conn(HTTP_ResponseBuilder builder)
if (server == NULL) if (server == NULL)
return NULL; return NULL;
if (server->index > HTTP_SERVER_CAPACITY) if (builder.index > HTTP_SERVER_CAPACITY)
return NULL; return NULL;
HTTP_ServerConn *conn = server->conns[server->index]; HTTP_ServerConn *conn = server->conns[builder.index];
if (conn->gen != builder.gen) if (builder.gen != conn->gen)
return NULL; return NULL;
return conn; return conn;
@@ -295,7 +327,7 @@ void http_response_builder_body(HTTP_ResponseBuilder builder, String str)
if (conn->state != HTTP_SERVER_CONN_WAIT_BODY) if (conn->state != HTTP_SERVER_CONN_WAIT_BODY)
return; return;
byte_queue_write(&conn->output, str); byte_queue_write(&conn->output, str.ptr, str.len);
} }
void http_response_builder_send(HTTP_ResponseBuilder builder, String str) void http_response_builder_send(HTTP_ResponseBuilder builder, String str)
+10
View File
@@ -68,6 +68,11 @@ typedef struct {
typedef struct { typedef struct {
// Size limit of the input and output buffer of each
// connection.
uint32_t input_buffer_limit;
uint32_t output_buffer_limit;
// Array of connections. The counter contains the // Array of connections. The counter contains the
// number of structs such that state=FREE. // number of structs such that state=FREE.
int num_conns; int num_conns;
@@ -105,6 +110,11 @@ int http_server_init(HTTP_Server *server);
// Release resources associated to the server. // Release resources associated to the server.
void http_server_free(HTTP_Server *server); void http_server_free(HTTP_Server *server);
// Set input and output buffer size limit for any
// given connection. The default value is 1MB
void http_server_set_input_limit(HTTP_Server *server, uint32_t limit);
void http_server_set_output_limit(HTTP_Server *server, uint32_t limit);
// Enable listening for plain HTTP requests at the // Enable listening for plain HTTP requests at the
// specified interface. // specified interface.
int http_server_listen_tcp(HTTP_Server *server, int http_server_listen_tcp(HTTP_Server *server,
+82 -67
View File
@@ -219,6 +219,15 @@ int socket_manager_add_certificate(SocketManager *sm,
return 0; return 0;
} }
static bool is_secure(Socket *s)
{
#ifdef HTTPS_ENABLED
return (s->ssl != NULL);
#else
return false;
#endif
}
static bool connect_pending(void) static bool connect_pending(void)
{ {
#ifdef _WIN32 #ifdef _WIN32
@@ -228,17 +237,6 @@ static bool connect_pending(void)
#endif #endif
} }
static bool
connect_failed_because_of_peer(void)
{
#ifdef _WIN32
int err = WSAGetLastError();
#else
int err = errno;
#endif
return connect_failed_because_of_peer_2(err);
}
static bool static bool
connect_failed_because_of_peer_2(int err) connect_failed_because_of_peer_2(int err)
{ {
@@ -255,10 +253,21 @@ connect_failed_because_of_peer_2(int err)
#endif #endif
} }
static bool
connect_failed_because_of_peer(void)
{
#ifdef _WIN32
int err = WSAGetLastError();
#else
int err = errno;
#endif
return connect_failed_because_of_peer_2(err);
}
// This function moves the socket state machine // This function moves the socket state machine
// to the next state until an I/O event would // to the next state until an I/O event would
// be required to continue. // be required to continue.
static void socket_update(Socket *socket) static void socket_update(Socket *s)
{ {
// Each case of this switch encodes a state transition. // Each case of this switch encodes a state transition.
// If the evaluated case requires a given I/O event to // If the evaluated case requires a given I/O event to
@@ -269,7 +278,7 @@ static void socket_update(Socket *socket)
bool again; bool again;
do { do {
again = false; again = false;
switch (socket->state) { switch (s->state) {
case SOCKET_STATE_PENDING: case SOCKET_STATE_PENDING:
{ {
// This point may be reached because // This point may be reached because
@@ -280,17 +289,17 @@ static void socket_update(Socket *socket)
// If (2) is true, we have some resources // If (2) is true, we have some resources
// to clean up. // to clean up.
if (socket->sock != NATIVE_SOCKET_INVALID) { if (s->sock != NATIVE_SOCKET_INVALID) {
// This is not the first attempt // This is not the first attempt
CLOSE_NATIVE_SOCKET(socket->sock); CLOSE_NATIVE_SOCKET(s->sock);
socket->next_addr++; s->next_addr++;
if (socket->next_addr == socket->num_addr) { if (s->next_addr == s->num_addr) {
assert(0); // TODO assert(0); // TODO
} }
} }
AddressAndPort addr = socket->addrs[socket->next_addr]; AddressAndPort addr = s->addrs[s->next_addr];
int family = (addr.is_ipv4 ? AF_INET : AF_INET6); int family = (addr.is_ipv4 ? AF_INET : AF_INET6);
NATIVE_SOCKET sock = socket(family, SOCK_STREAM, 0); NATIVE_SOCKET sock = socket(family, SOCK_STREAM, 0);
@@ -307,41 +316,39 @@ static void socket_update(Socket *socket)
struct sockaddr_in buf; struct sockaddr_in buf;
buf.sin_family = AF_INET; buf.sin_family = AF_INET;
buf.sin_port = htons(addr.port); buf.sin_port = htons(addr.port);
memset(&buf.sin_addr, &addr.ipv4, sizeof(IPv4)); memcpy(&buf.sin_addr, &addr.ipv4, sizeof(IPv4));
ret = connect(sock, (struct sockaddr*) &connect_buf, ret = connect(sock, (struct sockaddr*) &buf, sizeof(buf));
sizeof(connect_buf));
} else { } else {
struct sockaddr_in6 buf; struct sockaddr_in6 buf;
buf.sin6_family = AF_INET6; buf.sin6_family = AF_INET6;
buf.sin6_port = htons(addr.port); buf.sin6_port = htons(addr.port);
memset(&buf.sin6_addr, &addr.ipv6, sizeof(IPv6)); memcpy(&buf.sin6_addr, &addr.ipv6, sizeof(IPv6));
ret = connect(sock, (struct sockaddr*) &connect_buf, ret = connect(sock, (struct sockaddr*) &buf, sizeof(buf));
sizeof(connect_buf));
} }
if (ret == 0) { if (ret == 0) {
// Connect resolved immediately // Connect resolved immediately
socket->sock = sock; s->sock = sock;
socket->state = SOCKET_STATE_CONNECTED; s->state = SOCKET_STATE_CONNECTED;
socket->events = 0; s->events = 0;
again = true; again = true;
} else if (connect_pending()) { } else if (connect_pending()) {
// Connect is pending, which is expected // Connect is pending, which is expected
socket->sock = sock; s->sock = sock;
socket->state = SOCKET_STATE_CONNECTING; s->state = SOCKET_STATE_CONNECTING;
socket->events = POLLOUT; s->events = POLLOUT;
} else if (connect_failed_because_of_peer()) { } else if (connect_failed_because_of_peer()) {
// Conenct failed due to the peer host // Conenct failed due to the peer host
// We should try a different address. // We should try a different address.
socket->sock = sock; s->sock = sock;
socket->state = SOCKET_STATE_PENDING; s->state = SOCKET_STATE_PENDING;
socket->events = 0; s->events = 0;
again = true; again = true;
} else { } else {
// An error occurred that we can't recover from // An error occurred that we can't recover from
socket->sock = sock; s->sock = sock;
socket->state = SOCKET_STATE_DIED; s->state = SOCKET_STATE_DIED;
socket->events = 0; s->events = 0;
again = true; again = true;
} }
} }
@@ -354,23 +361,23 @@ static void socket_update(Socket *socket)
int err = 0; int err = 0;
socklen_t len = sizeof(err); socklen_t len = sizeof(err);
if (getsockopt(socket->sock, SOL_SOCKET, SO_ERROR, (void*) &err, &len) < 0) { if (getsockopt(s->sock, SOL_SOCKET, SO_ERROR, (void*) &err, &len) < 0) {
assert(0); // TODO assert(0); // TODO
} }
if (err == 0) { if (err == 0) {
// Connection succeded // Connection succeded
socket->state = SOCKET_STATE_CONNECTED; s->state = SOCKET_STATE_CONNECTED;
socket->events = 0; s->events = 0;
again = true; again = true;
} else if (connect_failed_because_of_peer_2(err)) { } else if (connect_failed_because_of_peer_2(err)) {
// Try the next address // Try the next address
socket->state = SOCKET_STATE_PENDING; s->state = SOCKET_STATE_PENDING;
socket->events = 0; s->events = 0;
again = true; again = true;
} else { } else {
socket->state = SOCKET_STATE_DIED; s->state = SOCKET_STATE_DIED;
socket->events = 0; s->events = 0;
} }
} }
break; break;
@@ -380,12 +387,25 @@ static void socket_update(Socket *socket)
// We managed to connect to the peer. // We managed to connect to the peer.
// We can free the target array if it // We can free the target array if it
// was allocated dynamically. // was allocated dynamically.
if (socket->num_addr > 1) if (s->num_addr > 1)
free(socket->addrs); free(s->addrs);
if (!is_secure(socket)) { if (!is_secure(s)) {
socket->events = 0; s->events = 0;
socket->state = SOCKET_STATE_ESTABLISHED_READY; s->state = SOCKET_STATE_ESTABLISHED_READY;
} else {
#ifdef HTTPS_ENABLED
assert(0); // TODO
#endif
}
}
break;
case SOCKET_STATE_ACCEPTED:
{
if (!is_secure(s)) {
s->state = SOCKET_STATE_ESTABLISHED_READY;
s->events = 0;
} else { } else {
#ifdef HTTPS_ENABLED #ifdef HTTPS_ENABLED
assert(0); // TODO assert(0); // TODO
@@ -395,15 +415,15 @@ static void socket_update(Socket *socket)
break; break;
case SOCKET_STATE_ESTABLISHED_WAIT: case SOCKET_STATE_ESTABLISHED_WAIT:
socket->state = SOCKET_STATE_ESTABLISHED_READY; s->state = SOCKET_STATE_ESTABLISHED_READY;
socket->events = 0; s->events = 0;
break; break;
case SOCKET_STATE_SHUTDOWN: case SOCKET_STATE_SHUTDOWN:
{ {
if (!is_secure(socket)) { if (!is_secure(s)) {
socket->state = SOCKET_STATE_DIED; s->state = SOCKET_STATE_DIED;
socket->events = 0; s->events = 0;
} else { } else {
#ifdef HTTPS_ENABLED #ifdef HTTPS_ENABLED
assert(0); // TODO assert(0); // TODO
@@ -544,7 +564,7 @@ static int socket_manager_translate_events_nolock(
bool secure = (polled[i].fd == sm->secure_sock); bool secure = (polled[i].fd == sm->secure_sock);
Socket *s = sm->sockets; Socket *s = sm->sockets;
while (s->type != SOCKET_FREE) { while (s->state != SOCKET_STATE_FREE) {
s++; s++;
assert(s - sm->sockets < + sm->max_used); assert(s - sm->sockets < + sm->max_used);
} }
@@ -570,7 +590,7 @@ static int socket_manager_translate_events_nolock(
continue; continue;
} }
pool->num_used++; sm->num_used++;
} else if (polled[i].fd == sm->wait_sock) { } else if (polled[i].fd == sm->wait_sock) {
@@ -584,7 +604,7 @@ static int socket_manager_translate_events_nolock(
for (int i = 0, j = 0; j < sm->num_used; i++) { for (int i = 0, j = 0; j < sm->num_used; i++) {
Socket *s = &sm->sockets[i]; Socket *s = &sm->sockets[i];
if (s->state == SOCKET_FREE) if (s->state == SOCKET_STATE_FREE)
continue; continue;
j++; j++;
@@ -600,7 +620,7 @@ static int socket_manager_translate_events_nolock(
}; };
// Free resources associated to socket // Free resources associated to socket
s->state = SOCKET_FREE; s->state = SOCKET_STATE_FREE;
if (s->sock != NATIVE_SOCKET_INVALID) if (s->sock != NATIVE_SOCKET_INVALID)
CLOSE_NATIVE_SOCKET(s->sock); CLOSE_NATIVE_SOCKET(s->sock);
if (s->sock == SOCKET_STATE_PENDING || if (s->sock == SOCKET_STATE_PENDING ||
@@ -717,7 +737,7 @@ int socket_connect(SocketManager *sm, int num_targets,
return -1; return -1;
Socket *s = sm->sockets; Socket *s = sm->sockets;
while (s->type != SOCKET_FREE) { while (s->state != SOCKET_STATE_FREE) {
s++; s++;
assert(s - sm->sockets < + sm->max_used); assert(s - sm->sockets < + sm->max_used);
} }
@@ -736,7 +756,7 @@ int socket_connect(SocketManager *sm, int num_targets,
s->addrs[i] = resolved[i]; s->addrs[i] = resolved[i];
} }
s->type = SOCKET_STATE_PENDING; s->state = SOCKET_STATE_PENDING;
s->sock = NATIVE_SOCKET_INVALID; s->sock = NATIVE_SOCKET_INVALID;
s->user = user; s->user = user;
s->num_used++; s->num_used++;
@@ -888,25 +908,20 @@ int socket_is_secure(SocketManager *sm, SocketHandle handle)
if (mutex_lock(&sm->mutex) < 0) if (mutex_lock(&sm->mutex) < 0)
return -1; return -1;
#ifdef HTTPS_ENABLED
Socket *s = handle_to_socket(sm, handle); Socket *s = handle_to_socket(sm, handle);
int ret; int ret;
if (s == NULL) if (s == NULL)
ret = -1; ret = -1;
else { else
ret = (s->ssl != NULL); ret = is_secure(s);
}
#else
int ret = 0;
#endif
if (mutex_unlock(&sm->mutex) < 0) if (mutex_unlock(&sm->mutex) < 0)
return -1; return -1;
return ret; return ret;
} }
int socket_set_user(SocketManager *sm, SocketHandle handle) int socket_set_user(SocketManager *sm, SocketHandle handle, void *user)
{ {
if (mutex_lock(&sm->mutex) < 0) if (mutex_lock(&sm->mutex) < 0)
return -1; return -1;
+7 -3
View File
@@ -102,10 +102,14 @@ typedef enum {
// still pending. // still pending.
SOCKET_STATE_CONNECTING, SOCKET_STATE_CONNECTING,
// The connection was estabished, but a TLS // Outgoing connection was established, but
// handshake may need to be performed. // a TLS handshake may need to be performed.
SOCKET_STATE_CONNECTED, SOCKET_STATE_CONNECTED,
// Incoming connection was established, but
// a TLS handshake may need to be performed.
SOCKET_STATE_ACCEPTED,
// The connection was esablished, but the user // The connection was esablished, but the user
// wants to perform a read or write operation that // wants to perform a read or write operation that
// would block. // would block.
@@ -299,4 +303,4 @@ void socket_close(SocketManager *sm, SocketHandle handle);
int socket_is_secure(SocketManager *sm, SocketHandle handle); int socket_is_secure(SocketManager *sm, SocketHandle handle);
// Set the user pointer of a socket // Set the user pointer of a socket
void socket_set_user(SocketManager *sm, SocketHandle handle); void socket_set_user(SocketManager *sm, SocketHandle handle, void *user);
+5 -3
View File
@@ -1,7 +1,9 @@
typedef struct { #ifdef _WIN32
char unused; // TODO typedef CRITICAL_SECTION Mutex;
} Mutex; #else
typedef pthread_mutex_t Mutex;
#endif
int mutex_init(Mutex *mutex); int mutex_init(Mutex *mutex);
int mutex_free(Mutex *mutex); int mutex_free(Mutex *mutex);