Skip to content

Commit

Permalink
proto_ws: refactor code
Browse files Browse the repository at this point in the history
Split the connection specific logic from the WS implementation
  • Loading branch information
razvancrainea committed Sep 3, 2015
1 parent a2e73ba commit a889f1e
Show file tree
Hide file tree
Showing 6 changed files with 204 additions and 183 deletions.
39 changes: 26 additions & 13 deletions modules/proto_ws/proto_ws.c
Expand Up @@ -39,30 +39,43 @@
#include "../../receive.h"
#include "../../timer.h"
#include "proto_ws.h"
#include "ws.h"

static int mod_init(void);
static int proto_ws_init(struct proto_info *pi);
static int proto_ws_init_listener(struct socket_info *si);
static int proto_ws_send(struct socket_info* send_sock,
char* buf, unsigned int len, union sockaddr_union* to, int id);
static int ws_read_req(struct tcp_connection* con, int* bytes_read);
static int ws_conn_init(struct tcp_connection* c);
static void ws_conn_clean(struct tcp_connection* c);
#include "ws_tcp.h"
#include "ws_common_defs.h"

/* parameters*/
int ws_max_msg_chunks = TCP_CHILD_MAX_MSG_CHUNK;

static struct tcp_req tcp_current_req;

static struct ws_req ws_current_req;

/* in milliseconds */
int ws_send_timeout = 100;

/* in milliseconds */
int ws_hs_read_tout = 100;

static int ws_port = WS_DEFAULT_PORT;
#define _ws_common_module "ws"
#define _ws_common_tcp_current_req tcp_current_req
#define _ws_common_current_req ws_current_req
#define _ws_common_max_msg_chunks ws_max_msg_chunks
#define _ws_common_read ws_raw_read
#define _ws_common_writev ws_raw_writev
#define _ws_common_read_tout ws_hs_read_tout
#define _ws_common_write_tout ws_send_timeout
#include "ws_handshake_common.h"
#include "ws_common.h"

/* XXX: this information should be dynamically provided */
str ws_resource = str_init("/");
static int mod_init(void);
static int proto_ws_init(struct proto_info *pi);
static int proto_ws_init_listener(struct socket_info *si);
static int proto_ws_send(struct socket_info* send_sock,
char* buf, unsigned int len, union sockaddr_union* to, int id);
static int ws_read_req(struct tcp_connection* con, int* bytes_read);
static int ws_conn_init(struct tcp_connection* c);
static void ws_conn_clean(struct tcp_connection* c);

static int ws_port = WS_DEFAULT_PORT;


static cmd_export_t cmds[] = {
Expand Down
60 changes: 31 additions & 29 deletions modules/proto_ws/ws.c → modules/proto_ws/ws_common.h
@@ -1,6 +1,5 @@
/*
* Copyright (C) 2015 - OpenSIPS Foundation
* Copyright (C) 2001-2003 FhG Fokus
*
* This file is part of opensips, a free SIP server.
*
Expand All @@ -24,8 +23,10 @@
* 2015-02-xx first version (razvanc)
*/

#ifndef _WS_COMMON_H_
#define _WS_COMMON_H_

#include "../../mem/shm_mem.h"
#include "../../net/net_tcp.h"
#include "../../globals.h"
#include "../../receive.h"
#include "../../dprint.h"
Expand All @@ -35,7 +36,7 @@
#include "../../pt.h"
#include "proto_ws.h"
#include "ws_tcp.h"
#include "ws.h"
#include "ws_common_defs.h"


/*
Expand Down Expand Up @@ -135,19 +136,19 @@
/* Returns the size of the mask, if needed */
#define WS_IF_MASK_SIZE(_r) (WS_IS_MASKED(_r) ? WS_MASK_SIZE : 0)



/* wrapper around tcp request to add ws info */
struct ws_req {
struct tcp_req tcp;
unsigned int op;
unsigned int mask;
unsigned int is_masked;
};

#define ROTATE32(_k) ((((_k) & 0xFF) << 24) | ((_k) >> 8))
#define MASK8(_k) ((unsigned char)((_k) & 0xFF))

#ifndef _ws_common_current_req
#error "_ws_common_current_req not defined!"
#endif
#ifndef _ws_common_writev
#error "_ws_common_writev not defined!"
#endif
#ifndef _ws_common_write_tout
#error "_ws_common_write_tout not defined!"
#endif

static inline void ws_print_masked(char *buf, int len)
{
static char *print_buf;
Expand Down Expand Up @@ -180,7 +181,7 @@ static inline void ws_print_masked(char *buf, int len)
LM_INFO("Print buffer\n%s", print_buf);
}

void inline ws_mask(char *buf, int len, unsigned int mask)
static inline void ws_mask(char *buf, int len, unsigned int mask)
{
char *p = buf;
char *end = buf + len;
Expand Down Expand Up @@ -219,7 +220,8 @@ static inline int ws_send(struct tcp_connection *con, int fd, int op,
if (len == 0) {
hdr_buf[1] = 0;
/* don't have any data, send only the heeader */
return ws_raw_write(con, fd, (char *)hdr_buf, WS_MIN_HDR_LEN);
v[0].iov_len = WS_MIN_HDR_LEN;
return _ws_common_writev(con, fd, v, 1, _ws_common_write_tout);
} else if (len < WS_EXT_LEN) {
hdr_buf[1] = len;
v[0].iov_len = WS_MIN_HDR_LEN;
Expand Down Expand Up @@ -256,7 +258,7 @@ static inline int ws_send(struct tcp_connection *con, int fd, int op,

v[1].iov_len = len;

return ws_raw_writev(con, fd, v, 2);
return _ws_common_writev(con, fd, v, 2, _ws_common_write_tout);
}

static inline int ws_send_pong(struct tcp_connection *con, struct ws_req *req)
Expand Down Expand Up @@ -284,13 +286,11 @@ static inline int ws_send_close(struct tcp_connection *con)

/* Public functions down here */

int ws_req_write(struct tcp_connection *con, int fd, char *buf, int len)
static int ws_req_write(struct tcp_connection *con, int fd, char *buf, int len)
{
return ws_send(con, fd, WS_OP_TEXT, buf, len);
}

static struct ws_req ws_current_req;

static enum ws_close_code inline ws_parse(struct ws_req *req)
{

Expand Down Expand Up @@ -397,7 +397,7 @@ static enum ws_close_code inline ws_parse(struct ws_req *req)
(_req)->is_masked = 0; \
} while(0)

int ws_process(struct tcp_connection *con)
static int ws_process(struct tcp_connection *con)
{
struct ws_req *req;
struct ws_req *newreq;
Expand All @@ -413,14 +413,14 @@ int ws_process(struct tcp_connection *con)
LM_DBG("Using the per connection buff \n");
} else {
LM_DBG("Using the global ( per process ) buff \n");
init_ws_req(&ws_current_req, 0);
req=&ws_current_req;
init_ws_req(&_ws_common_current_req, 0);
req=&_ws_common_current_req;
}

again:
if (req->tcp.error == TCP_REQ_OK) {
if (req->tcp.parsed >= req->tcp.pos) {
if (ws_raw_read(con, &req->tcp) < 0) {
if (_ws_common_read(con, &req->tcp) < 0) {
LM_ERR("failed to read %d:%s\n", errno, strerror(errno));
goto error;
}
Expand Down Expand Up @@ -452,7 +452,7 @@ int ws_process(struct tcp_connection *con)
if (req->tcp.complete) {

/* update the timeout - we successfully read the request */
tcp_conn_set_lifetime(con, ws_send_timeout);
tcp_conn_set_lifetime(con, _ws_common_write_tout);
con->timeout=con->lifetime;

/* if we are here everything is nice and ok*/
Expand Down Expand Up @@ -515,7 +515,7 @@ int ws_process(struct tcp_connection *con)
* the connection */
LM_DBG("We're releasing the connection in state %d \n",
con->state);
if (req != &ws_current_req) {
if (req != &_ws_common_current_req) {
/* we have the buffer in the connection tied buff -
* detach it , release the conn and free it afterwards */
con->con_req = NULL;
Expand Down Expand Up @@ -553,20 +553,20 @@ int ws_process(struct tcp_connection *con)
if (size)
goto again;
/* cleanup the existing request */
if (req != &ws_current_req)
if (req != &_ws_common_current_req)
pkg_free(req);

} else {
/* request not complete - check the if the thresholds are exceeded */

con->msg_attempts++;
if (con->msg_attempts == ws_max_msg_chunks) {
if (con->msg_attempts == _ws_common_max_msg_chunks) {
LM_ERR("Made %u read attempts but message is not complete yet - "
"closing connection \n",con->msg_attempts);
goto error;
}

if (req == &ws_current_req) {
if (req == &_ws_common_current_req) {
/* let's duplicate this - most likely another conn will come in */

LM_DBG("We didn't manage to read a full request\n");
Expand Down Expand Up @@ -627,7 +627,9 @@ int ws_process(struct tcp_connection *con)
return -1;
}

void ws_close(struct tcp_connection *c)
static void ws_close(struct tcp_connection *c)
{
ws_send_close(c);
}

#endif /* _WS_COMMON_H_ */
27 changes: 11 additions & 16 deletions modules/proto_ws/ws.h → modules/proto_ws/ws_common_defs.h
@@ -1,6 +1,5 @@
/*
* Copyright (C) 2015 - OpenSIPS Foundation
* Copyright (C) 2001-2003 FhG Fokus
*
* This file is part of opensips, a free SIP server.
*
Expand All @@ -24,22 +23,18 @@
* 2015-02-xx first version (razvanc)
*/

#ifndef _WS_H_
#define _WS_H_
#ifndef _WS_COMMON_DEFS_H_
#define _WS_COMMON_DEFS_H_

/* borrow suff from proto_tcp - but don't use parse and common */
#include "../../net/proto_tcp/tcp_common_defs.h"
#include "../../net/net_tcp.h"

/* wrapper around tcp request to add ws info */
struct ws_req {
struct tcp_req tcp;
unsigned int op;
unsigned int mask;
unsigned int is_masked;
};

extern int ws_max_msg_chunks;
extern int ws_send_timeout;
extern str ws_resource;
extern int ws_hs_read_tout;

void ws_close(struct tcp_connection *con);
int ws_process(struct tcp_connection *con);
int ws_server_handshake(struct tcp_connection *con);
int ws_client_handshake(struct tcp_connection *con);
int ws_req_write(struct tcp_connection *con, int fd, char *buf, int len);

#endif /* _WS_H_ */
#endif /* _WS_COMMON_DEFS_H_ */

0 comments on commit a889f1e

Please sign in to comment.