Skip to content

Commit

Permalink
Enhancement: Replace 'fd' with 'ws_cli_conn_t' throughout the code
Browse files Browse the repository at this point in the history
This commit changes the use of the 'fd' parameter of the wsServer's
API and replaces it with a pointer of type 'ws_cli_conn_t'.

This change brings multiple benefits to the source code:
a) The 'fd' could confuse the user and cause them to use it in other
POSIX routines that accept a file descriptor.

b) Sharing the 'fd' through various functions and iterating over the
list of clients to get the structure of it sounds completely pointless.

Therefore, the natural solution is to share the pointer relative to
the client's connection structure, which improves code complexity,
readability, and reduces the amount of LOCs.

--
Furthermore, this commit also changes the way broadcast messages are
sent: previously, to send a broadcast it was necessary to know the
'fd' of a valid connected client, which also doesn't make sense.
Therefore, the signing of the ws_sendframe* functions has been
simplified, and the 'broadcast' parameter is no longer needed. If the
recipient is null, the message is a broadcast.
---

Note: The multi-port listening feature has been removed in order to
make the broadcast mechanism simpler. However, I intend reintroduce
it in the future by removing all public variables and leaving the
event frame bound to a 'struct ws_server'.
  • Loading branch information
Theldus committed Apr 5, 2022
1 parent 73c94a4 commit cb2c3f8
Show file tree
Hide file tree
Showing 4 changed files with 245 additions and 329 deletions.
43 changes: 23 additions & 20 deletions example/send_receive.c
Expand Up @@ -32,43 +32,43 @@
/**
* @brief Called when a client connects to the server.
*
* @param fd File Descriptor belonging to the client. The @p fd parameter
* is used in order to send messages and retrieve informations
* about the client.
* @param client Client connection. The @p client parameter is used
* in order to send messages and retrieve informations about the
* client.
*/
void onopen(int fd)
void onopen(ws_cli_conn_t *client)
{
char *cli;
cli = ws_getaddress(fd);
cli = ws_getaddress(client);
#ifndef DISABLE_VERBOSE
printf("Connection opened, client: %d | addr: %s\n", fd, cli);
printf("Connection opened, addr: %s\n", cli);
#endif
free(cli);
}

/**
* @brief Called when a client disconnects to the server.
*
* @param fd File Descriptor belonging to the client. The @p fd parameter
* is used in order to send messages and retrieve informations
* about the client.
* @param client Client connection. The @p client parameter is used
* in order to send messages and retrieve informations about the
* client.
*/
void onclose(int fd)
void onclose(ws_cli_conn_t *client)
{
char *cli;
cli = ws_getaddress(fd);
cli = ws_getaddress(client);
#ifndef DISABLE_VERBOSE
printf("Connection closed, client: %d | addr: %s\n", fd, cli);
printf("Connection closed, addr: %s\n", cli);
#endif
free(cli);
}

/**
* @brief Called when a client connects to the server.
*
* @param fd File Descriptor belonging to the client. The
* @p fd parameter is used in order to send messages and
* retrieve informations about the client.
* @param client Client connection. The @p client parameter is used
* in order to send messages and retrieve informations about the
* client.
*
* @param msg Received message, this message can be a text
* or binary message.
Expand All @@ -77,13 +77,14 @@ void onclose(int fd)
*
* @param type Message type.
*/
void onmessage(int fd, const unsigned char *msg, uint64_t size, int type)
void onmessage(ws_cli_conn_t *client,
const unsigned char *msg, uint64_t size, int type)
{
char *cli;
cli = ws_getaddress(fd);
cli = ws_getaddress(client);
#ifndef DISABLE_VERBOSE
printf("I receive a message: %s (size: %" PRId64 ", type: %d), from: %s/%d\n",
msg, size, type, cli, fd);
printf("I receive a message: %s (size: %" PRId64 ", type: %d), from: %s\n",
msg, size, type, cli);
#endif
free(cli);

Expand All @@ -94,8 +95,10 @@ void onmessage(int fd, const unsigned char *msg, uint64_t size, int type)
* or ws_sendframe_bin() here, but we're just being safe
* and re-sending the very same frame type and content
* again.
*
* Client equals to NULL: broadcast
*/
ws_sendframe(fd, (char *)msg, size, true, type);
ws_sendframe(NULL, (char *)msg, size, type);
}

/**
Expand Down
46 changes: 22 additions & 24 deletions include/ws.h
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2016-2021 Davidson Francis <davidsondfgl@gmail.com>
* Copyright (C) 2016-2022 Davidson Francis <davidsondfgl@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -42,13 +42,6 @@ extern "C" {
*/
#define MAX_CLIENTS 8

/**
* @brief Max number of `ws_server` instances running
* at the same time.
*/
#define MAX_PORTS 16
/**@}*/

/**
* @name Key and message configurations.
*/
Expand Down Expand Up @@ -222,15 +215,16 @@ extern "C" {
/**@}*/

#ifndef AFL_FUZZ
#define CLI_SOCK(sock) (sock)
#define SEND(fd,buf,len,idx) send_all((fd), (buf), (len), MSG_NOSIGNAL, (idx))
#define RECV(fd,buf,len) recv((fd), (buf), (len), 0)
#define SEND(client,buf,len) send_all((client), (buf), (len), MSG_NOSIGNAL)
#define RECV(fd,buf,len) recv((fd)->client_sock, (buf), (len), 0)
#else
#define CLI_SOCK(sock) (fileno(stdout))
#define SEND(fd,buf,len,idx) write(fileno(stdout), (buf), (len))
#define RECV(fd,buf,len) read((fd), (buf), (len))
#define SEND(client,buf,len) write(fileno(stdout), (buf), (len))
#define RECV(fd,buf,len) read((fd)->client_sock, (buf), (len))
#endif

/* Opaque client connection type. */
typedef struct ws_connection ws_cli_conn_t;

/**
* @brief events Web Socket events types.
*/
Expand All @@ -239,31 +233,35 @@ extern "C" {
/**
* @brief On open event, called when a new client connects.
*/
void (*onopen)(int);
void (*onopen)(ws_cli_conn_t *client);

/**
* @brief On close event, called when a client disconnects.
*/
void (*onclose)(int);
void (*onclose)(ws_cli_conn_t *client);

/**
* @brief On message event, called when a client sends a text
* or binary message.
*/
void (*onmessage)(int, const unsigned char *, uint64_t, int);
void (*onmessage)(ws_cli_conn_t *client,
const unsigned char *msg, uint64_t msg_size, int type);
};

/* Forward declarations. */

/* Internal usage. */
extern int get_handshake_accept(char *wsKey, unsigned char **dest);
extern int get_handshake_response(char *hsrequest, char **hsresponse);
extern char *ws_getaddress(int fd);

/* External usage. */
extern char *ws_getaddress(ws_cli_conn_t *client);
extern int ws_sendframe(
int fd, const char *msg, uint64_t size, bool broadcast, int type);
extern int ws_sendframe_txt(int fd, const char *msg, bool broadcast);
extern int ws_sendframe_bin(int fd, const char *msg, uint64_t size,
bool broadcast);
extern int ws_get_state(int fd);
extern int ws_close_client(int fd);
ws_cli_conn_t *cli, const char *msg, uint64_t size, int type);
extern int ws_sendframe_txt(ws_cli_conn_t *cli, const char *msg);
extern int ws_sendframe_bin(ws_cli_conn_t *cli, const char *msg, uint64_t size);
extern int ws_get_state(ws_cli_conn_t *cli);
extern int ws_close_client(ws_cli_conn_t *cli);
extern int ws_socket(struct ws_events *evs, uint16_t port, int thread_loop);

#ifdef AFL_FUZZ
Expand Down

0 comments on commit cb2c3f8

Please sign in to comment.