Module: sip-router
Branch: master
Commit: 2f240d5f5d1e647cbc6ee55893a65058bf950cda
URL:
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=2f240d5…
Author: Peter Dunkley <peter.dunkley(a)crocodile-rcs.com>
Committer: Peter Dunkley <peter.dunkley(a)crocodile-rcs.com>
Date: Thu Oct 11 12:58:38 2012 +0100
modules/msrp: Added support for WS transport
- Updated parser to recognise/decode ";ws" as a transport
- Updated netio code to route MSRP messages destined for a
WebSocket connection through the websocket module (instead of just
tcp_send()ing them).
---
modules/msrp/msrp_netio.c | 59 +++++++++++++++++++++++++++++++++++++++++++-
modules/msrp/msrp_parser.c | 6 +++-
modules/msrp/msrp_parser.h | 1 +
3 files changed, 63 insertions(+), 3 deletions(-)
diff --git a/modules/msrp/msrp_netio.c b/modules/msrp/msrp_netio.c
index 3c12355..86e16d6 100644
--- a/modules/msrp/msrp_netio.c
+++ b/modules/msrp/msrp_netio.c
@@ -66,6 +66,7 @@ int msrp_send_buffer(str *buf, str *addr, int flags)
int msrp_relay(msrp_frame_t *mf)
{
struct dest_info *dst;
+ struct tcp_connection *con = NULL;
char reqbuf[MSRP_MAX_FRAME_SIZE];
msrp_hdr_t *tpath;
msrp_hdr_t *fpath;
@@ -73,6 +74,7 @@ int msrp_relay(msrp_frame_t *mf)
str_array_t *sar;
char *p;
char *l;
+ int port;
if(mf->buf.len>=MSRP_MAX_FRAME_SIZE-1)
return -1;
@@ -136,7 +138,39 @@ int msrp_relay(msrp_frame_t *mf)
}
dst = &env->dstinfo;
done:
- if (tcp_send(dst, 0, reqbuf, p - reqbuf) < 0) {
+ port = su_getport(&dst->to);
+ if (likely(port))
+ {
+ ticks_t con_lifetime;
+ struct ip_addr ip;
+
+ con_lifetime = cfg_get(tcp, tcp_cfg, con_lifetime);
+ su2ip_addr(&ip, &dst->to);
+ con = tcpconn_get(dst->id, &ip, port, NULL, con_lifetime);
+ }
+ else if (likely(dst->id))
+ {
+ con = tcpconn_get(dst->id, 0, 0, 0, 0);
+ }
+
+ if (con == NULL)
+ {
+ LM_WARN("TCP/TLS connection not found\n");
+ return -1;
+ }
+
+ if (unlikely((con->rcv.proto == PROTO_WS || con->rcv.proto == PROTO_WSS)
+ && sr_event_enabled(SREV_TCP_WS_FRAME_OUT))) {
+ ws_event_info_t wsev;
+
+ memset(&wsev, 0, sizeof(ws_event_info_t));
+ wsev.type = SREV_TCP_WS_FRAME_OUT;
+ wsev.buf = reqbuf;
+ wsev.len = p - reqbuf;
+ wsev.id = con->id;
+ return sr_event_exec(SREV_TCP_WS_FRAME_OUT, (void *) &wsev);
+ }
+ else if (tcp_send(dst, 0, reqbuf, p - reqbuf) < 0) {
LM_ERR("forwarding frame failed\n");
return -1;
}
@@ -239,6 +273,29 @@ int msrp_reply(msrp_frame_t *mf, str *code, str *text, str *xhdrs)
*(p-3) = '$';
env = msrp_get_env();
+
+ if (unlikely((env->srcinfo.proto == PROTO_WS
+ || env->srcinfo.proto == PROTO_WSS)
+ && sr_event_enabled(SREV_TCP_WS_FRAME_OUT))) {
+ struct tcp_connection *con = tcpconn_get(env->srcinfo.id, 0, 0,
+ 0, 0);
+ ws_event_info_t wsev;
+
+ if (con == NULL)
+ {
+ LM_WARN("TCP/TLS connection for WebSocket could not be"
+ "found\n");
+ return -1;
+ }
+
+ memset(&wsev, 0, sizeof(ws_event_info_t));
+ wsev.type = SREV_TCP_WS_FRAME_OUT;
+ wsev.buf = rplbuf;
+ wsev.len = p - rplbuf;
+ wsev.id = con->id;
+ return sr_event_exec(SREV_TCP_WS_FRAME_OUT, (void *) &wsev);
+ }
+ else
if (tcp_send(&env->srcinfo, 0, rplbuf, p - rplbuf) < 0) {
LM_ERR("sending reply failed\n");
return -1;
diff --git a/modules/msrp/msrp_parser.c b/modules/msrp/msrp_parser.c
index 711f8dd..3f7e336 100644
--- a/modules/msrp/msrp_parser.c
+++ b/modules/msrp/msrp_parser.c
@@ -505,10 +505,12 @@ int msrp_parse_uri(char *start, int len, msrp_uri_t *uri)
if(uri->params.len > 0)
{
uri->proto.s = uri->params.s;
- if(uri->params.len > 3 && strncasecmp(uri->params.s, "tcp",
3)==0)
- {
+ if(uri->params.len > 3 && strncasecmp(uri->params.s, "tcp",
3)==0) {
uri->proto.len = 3;
uri->proto_no = MSRP_PROTO_TCP;
+ } else if (uri->params.len > 2 && strncasecmp(uri->params.s,
"ws", 2)==0) {
+ uri->proto.len = 2;
+ uri->proto_no = MSRP_PROTO_WS;
} else {
p = q_memchr(uri->params.s, ';', uri->params.len);
if(p!=NULL) {
diff --git a/modules/msrp/msrp_parser.h b/modules/msrp/msrp_parser.h
index 5117d60..9ea5e30 100644
--- a/modules/msrp/msrp_parser.h
+++ b/modules/msrp/msrp_parser.h
@@ -58,6 +58,7 @@ typedef struct msrp_fline {
#define MSRP_SCHEME_MSRPS 2
#define MSRP_PROTO_TCP 1
+#define MSRP_PROTO_WS 2
typedef struct msrp_uri {
str buf;