Connection* Connection_create(const char* ip, Uint16 port) { Connection* self = (Connection*)calloc(1, sizeof(Connection)); if(!self) { return NULL; } if(SDLNet_ResolveHost(&self->address, ip, port)) { Connection_destroy(&self); return NULL; } if(!(self->socket = SDLNet_TCP_Open(&self->address))) { Connection_destroy(&self); return NULL; } if(!(self->socket_set = SDLNet_AllocSocketSet(1))) { Connection_destroy(&self); return NULL; } if(SDLNet_TCP_AddSocket(self->socket_set, self->socket) == -1) { Connection_destroy(&self); return NULL; } if(SDLNet_CheckSockets(self->socket_set, 5000) == 1) { Uint8 message = Connection_recv_flag(self); if(message == CONNECTED) { Uint8 buffer[6] = {0}; Connection_recv_data(self, buffer, 6); self->local_address.host = SDLNet_Read32(buffer); self->local_address.port = SDLNet_Read16(buffer + 4); printf("Successfully connected to server\n"); return self; } else if(message == FULL) { printf("Server is full\n"); } } else { printf("Server is not responding\n"); } Connection_destroy(&self); return NULL; }
static inline int Server_accept(int listen_fd) { int cfd = -1; int rport = -1; char remote[IPADDR_SIZE]; int rc = 0; Connection *conn = NULL; cfd = netaccept(listen_fd, remote, &rport); check(cfd >= 0, "Failed to accept on listening socket."); Server *srv = Server_queue_latest(); check(srv != NULL, "Failed to get a server from the configured queue."); conn = Connection_create(srv, cfd, rport, remote); check(conn != NULL, "Failed to create connection after accept."); rc = Connection_accept(conn); check(rc == 0, "Failed to register connection, overloaded."); return 0; error: if(conn != NULL) Connection_destroy(conn); return -1; }
Connection *Connection_create(Server *srv, int fd, int rport, const char *remote, SSL_CTX *ssl_ctx) { Connection *conn = h_calloc(sizeof(Connection), 1); check_mem(conn); conn->server = srv; conn->rport = rport; memcpy(conn->remote, remote, IPADDR_SIZE); conn->remote[IPADDR_SIZE] = '\0'; conn->type = 0; conn->req = Request_create(); check_mem(conn->req); if(ssl_ctx != NULL) { conn->iob = IOBuf_create(BUFFER_SIZE, fd, IOBUF_SSL); check(conn->iob != NULL, "Failed to create the SSL IOBuf."); conn->iob->ssl = ssl_server_new(ssl_ctx, IOBuf_fd(conn->iob)); check(conn->iob->ssl != NULL, "Failed to create new ssl for connection"); } else { conn->iob = IOBuf_create(BUFFER_SIZE, fd, IOBUF_SOCKET); } return conn; error: Connection_destroy(conn); return NULL; }
void Connection_task(void *v) { Connection *conn = (Connection *)v; int i = 0; int next = OPEN; State_init(&conn->state, &CONN_ACTIONS); while(1) { if(Filter_activated()) { next = Filter_run(next, conn); check(next >= CLOSE && next < EVENT_END, "!!! Invalid next event[%d]: %d from filter!", i, next); } if(next == CLOSE) break; next = State_exec(&conn->state, next, (void *)conn); check(next >= CLOSE && next < EVENT_END, "!!! Invalid next event[%d]: %d, Tell ZED!", i, next); if(conn->iob && !conn->iob->closed) { Register_ping(IOBuf_fd(conn->iob)); } i++; } error: // fallthrough State_exec(&conn->state, CLOSE, (void *)conn); Connection_destroy(conn); taskexit(0); }
void Connection_send_flag(Connection* self, Uint8 flag) { if(SDLNet_TCP_Send(self->socket, &flag, 1) < 1) { printf("Lost connection to server\n"); Connection_destroy(&self); } }
void Connection_recv_data(Connection* self, Uint8* buffer, int size) { if(SDLNet_TCP_Recv(self->socket, buffer, size) < size) { printf("Lost connection to server\n"); Connection_destroy(&self); } }
void Connection_send_data(Connection* self, Uint8* data, int size) { if(SDLNet_TCP_Send(self->socket, data, size) < size) { printf("Lost connection to server\n"); Connection_destroy(&self); } }
Uint8 Connection_recv_flag(Connection* self) { Uint8 flag; if(SDLNet_TCP_Recv(self->socket, &flag, 1) < 1) { printf("Lost connection to server\n"); Connection_destroy(&self); } return flag; }
void Connection_task(void *v) { Connection *conn = (Connection *)v; int i = 0; int next = 0; State_init(&conn->state, &CONN_ACTIONS); for(i = 0, next = OPEN; next != CLOSE; i++) { next = State_exec(&conn->state, next, (void *)conn); check(next >= CLOSE && next < EVENT_END, "!!! Invalid next event[%d]: %d, Tell ZED!", i, next); } error: // fallthrough State_exec(&conn->state, CLOSE, (void *)conn); Connection_destroy(conn); return; }
Connection *Connection_create(Server *srv, int fd, int rport, const char *remote) { Connection *conn = calloc(sizeof(Connection),1); check_mem(conn); conn->req = Request_create(); conn->proxy_iob = NULL; conn->rport = rport; conn->client = NULL; conn->close = 0; conn->type = 0; conn->filter_state = NULL; memcpy(conn->remote, remote, IPADDR_SIZE); conn->remote[IPADDR_SIZE] = '\0'; conn->handler = NULL; check_mem(conn->req); if(srv != NULL && srv->use_ssl) { conn->iob = IOBuf_create(BUFFER_SIZE, fd, IOBUF_SSL); check(conn->iob != NULL, "Failed to create the SSL IOBuf."); ssl_set_own_cert(&conn->iob->ssl, &srv->own_cert, &srv->rsa_key); ssl_set_dh_param(&conn->iob->ssl, srv->dhm_P, srv->dhm_G); ssl_set_ciphersuites(&conn->iob->ssl, srv->ciphers); } else { conn->iob = IOBuf_create(BUFFER_SIZE, fd, IOBUF_SOCKET); } return conn; error: Connection_destroy(conn); return NULL; }
void fake_conn_close(Connection *conn) { assert(conn && conn->iob && "Invalid connection."); Register_disconnect(conn->iob->fd); Connection_destroy(conn); }