Files
@ eb391af42d62
Branch filter:
Location: DistRen/src/server/listen.h
eb391af42d62
6.2 KiB
text/plain
Non-working tabletennis, better poll() resiliency, some fixups to the slave, etc.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 | /*
Copyright 2010 Nathan Phillip Brink
This file is a part of DistRen.
DistRen is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
DistRen is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with DistRen. If not, see <http://www.gnu.org/licenses/>.
*/
/**
@file listen provides the ability to set up a listening socket
through multiio's poll() interface. This means that if the listen()-ish
libc calls we use are incompatible with windows, we don't have to
throw ifdefs all throughout src/common. We just put that code in the
only place that needs it: in src/server.
*/
struct general_info;
struct distrend_listens;
struct distrend_client;
#ifndef _DISTREN_LISTEN_H
#define _DISTREN_LISTEN_H
#include "distrend.h"
#include "tabletennis.h"
#include "common/options.h"
#include "common/multiio.h"
#include "common/protocol.h"
#include "common/remoteio.h"
#include <queue.h>
#include <time.h>
/**
How long a client has after connecting to send
authentication information before his connection is cleaned
up.
*/
#define DISTREND_LISTEN_AUTHTIME 32
/**
How long a client has when in DISTREND_CLIENT_BAD before
his connection is dropped. This grace time is intended so that
the client will actually see his disconnect message instead of
just having his connection reset.
*/
#define DISTREND_LISTEN_DISCONNECT_GRACE 8
enum distrend_client_state
{
/**
The client hasn't yet given us its version.
*/
DISTREND_CLIENT_PREVERSION,
/**
We don't yet know the client. It may only use authentication
commands.
*/
DISTREND_CLIENT_PREAUTH,
/**
The client is authenticated, etc.
*/
DISTREND_CLIENT_GOOD,
/**
The client is queued to be disconnected. (This state exists
so that the client at least has a chance to recieve its
disconnect message/error before being dumped).
*/
DISTREND_CLIENT_BAD,
};
struct distrend_listens
{
/* of type (struct distrend_request_handler_info) */
list_t request_handlers;
/* the data to pass on to all request handlers */
struct general_info *geninfo;
/* the distrend config */
struct options_common *options;
tabletennis_t tabletennis;
/* of type (struct distrend_client) (multiio stores a pointer per socket, we'll store each strut distrend_client as that pointer instead of using this list) */
/* list_t clients; */
/* the multiio context the listening interface should use/initialize */
multiio_context_t multiio;
/*
* the socket type reserved for us, i.e., the listen()/accept()
* socket type whose events we handle.
*/
multiio_socket_type_t socket_type;
};
/**
The information necessary to recieve data from and send data
to a client.
*/
struct distrend_client
{
enum distrend_client_state state;
/**
The absolute time at which this client's entry in the client list will be
expired, closed, and marked as dead so that it may be cleaned up. This is
used to implement ping timeouts (if state == DISTREND_CLIENT_GOOD) and
disconnect message grace time (if state == DISTREND_CLIENT_BAD).
*/
time_t cleanup_time;
size_t inlen; /*< number of bytes waiting to be processed */
size_t expectlen; /*< number of bytes that inlen has to be for a complete request to be had, 0 when waiting on header */
struct tabletennis_client tabletennis_client;
/**
* Yes, even though the remoteio will have a void *pointer to this
* struct, we need a reverse pointer for something like
* distrend_client_write() to work.
*/
struct remoteio *rem;
};
/**
A function signature that may be registered as a client
request handler.
@param client the client that sent the request
@param len the length of the message in bytes
@param data the message received from the client
*/
typedef int(*distrend_handle_request_func_t)(struct general_info *geninfo, struct distrend_client *client, size_t req_len, void *req_data);
/**
Initializes the listens member of struct distrend_config.
@param multiio the multiio context in which we should register a new socket type and insert records for clients who connect.
@param geninfo general info to apss to the request handler.
@return Must be free()d with distrend_listen_free();
*/
struct distrend_listens *distrend_listens_new(multiio_context_t multiio, struct general_info *geninfo, struct options_common *opts);
/**
Adds a socket and configures it to listen().
@param listens The handle for this set of listens, obtained via distrend_listen_init().
*/
int distrend_listen_add(struct distrend_listens *listens, int port);
/**
* Register a request handler with the listener.
*
* @param config distrend's configuration
* @param type the request type for which this handler should be called
* @param handler the handler to call when a request of type type is received.
*/
int distrend_listen_handler_add(struct distrend_listens *listens, enum distren_request_type type, distrend_handle_request_func_t handler);
/**
* cleans listening sockets/frees main struct. Unnecessary for a working server, currently a stub.
*/
int distrend_listen_free(struct distrend_listens *listens);
/**
writes request to client.
@param client client to write to
@param req the request struct. caller must free this.
@param data the data of the request which is req->len bytes long. caller must free this.
*/
int distrend_client_write_request(struct distrend_client *client, const struct distren_request *req, const void *data);
/**
This is probably just NOT a placeholder for remotio
*/
void remotio_send_to_client();
/**
* Queue a DISTREN_REQUEST_DISCONNECT and prepare a client
* to be disconnected.
*/
int distrend_send_disconnect(struct distrend_client *client, const char *quit_msg);
#endif
|