Explorar el Código

unixsock version of t_reply

Jan Janak hace 21 años
padre
commit
03416c6bc2
Se han modificado 3 ficheros con 194 adiciones y 1 borrados
  1. 181 1
      modules/tm/t_reply.c
  2. 2 0
      modules/tm/t_reply.h
  3. 11 0
      modules/tm/tm.c

+ 181 - 1
modules/tm/t_reply.c

@@ -80,6 +80,7 @@
 #include "../../data_lump_rpl.h"
 #include "../../usr_avp.h"
 #include "../../fifo_server.h"
+#include "../../unixsock_server.h"
 
 #include "defs.h"
 #include "h_table.h"
@@ -1436,7 +1437,7 @@ int fifo_t_reply( FILE *stream, char *response_file )
 		fifo_reply(response_file, "400 fifo_t_reply: while reading "
 			"new headers");
 		return -1;
-    }
+	}
 	snh.s[snh.len]='\0';
 	DBG("DEBUG: fifo_t_reply: new headers: %.*s\n", snh.len, snh.s);
 
@@ -1467,3 +1468,182 @@ int fifo_t_reply( FILE *stream, char *response_file )
 }
 
 
+static int parse_transid(str* s, unsigned int* index, unsigned int* label)
+{
+	char* buf;
+
+	if (!s || !index || !label) {
+		LOG(L_ERR, "parse_transid: Invalid parameter value\n");
+		return -1;
+	}
+
+	buf = (char*)pkg_malloc(s->len + 1);
+	if (!buf) {
+		LOG(L_ERR, "parse_transid: No memory left\n");
+		return -1;
+	}
+
+	memcpy(buf, s->s, s->len + 1);
+	buf[s->len] = '\0';
+	
+	if (sscanf(buf, "%u:%u", index, label) != 2) {
+		LOG(L_ERR, "parse_transid: Invalid trans_id (%s)\n", buf);
+		pkg_free(buf);
+		return -1;
+	}
+
+	DBG("parse_transid: hash_index=%u label=%u\n", *index, *label);
+	pkg_free(buf);
+	return 0;
+}
+
+
+
+static int send_reply(struct cell *trans, unsigned int code, str* text, str* body, str* headers, str* to_tag)
+{
+	struct lump_rpl *hdr_lump, *body_lump;
+	str rpl;
+	int ret;
+	struct bookmark bm;
+
+	     /* mark the transaction as replied */
+	if (code >= 200) set_kr(REQ_RPLD);
+
+	     /* add the lumps for new_header and for body (by bogdan) */
+	hdr_lump = add_lump_rpl(trans->uas.request, headers->s, headers->len, LUMP_RPL_HDR);
+	if (!hdr_lump) {
+		LOG(L_ERR, "send_reply: cannot add hdr lump\n");
+		goto sr_error;
+	}
+
+	     /* body lump */
+	if (body && body->len) {
+		body_lump = add_lump_rpl(trans->uas.request, body->s, body->len, LUMP_RPL_BODY);
+		if (body_lump == 0) {
+			LOG(L_ERR,"send_reply: cannot add body lump\n");
+			goto sr_error_1;
+		}
+	} else {
+		body_lump = 0;
+	}
+
+	     /* We can safely zero-terminate the text here, because it is followed
+	      * by next line in the received message
+	      */
+	text->s[text->len] = '\0';
+	rpl.s = build_res_buf_from_sip_req(code, text->s, to_tag, trans->uas.request, (unsigned int*)&rpl.len, &bm);
+
+	     /* since the msg (trans->uas.request) is a clone into shm memory, to avoid
+	      * memory leak or crashing (lumps are create in private memory) I will
+	      * remove the lumps by myself here (bogdan) */
+	unlink_lump_rpl(trans->uas.request, hdr_lump);
+	free_lump_rpl(hdr_lump);
+	if (body_lump) {
+		unlink_lump_rpl(trans->uas.request, body_lump);
+		free_lump_rpl(body_lump);
+	}
+
+	if (rpl.s == 0) {
+		LOG(L_ERR,"send_reply: failed in build_res_buf_from_sip_req\n");
+		goto sr_error;
+	}
+
+	ret = _reply_light(trans, rpl.s, rpl.len, code, text->s,  to_tag->s, to_tag->len, 1 /* lock replies */, &bm);
+	     /* this is ugly hack -- the function caller may wish to continue with
+	      * transction and I unref; however, there is now only one use from
+	      * vm/fifo_vm_reply and I'm currently to lazy to export UNREF; -jiri
+	      */
+	UNREF(trans);
+	return ret;
+ sr_error_1:
+
+	unlink_lump_rpl(trans->uas.request, hdr_lump);
+	free_lump_rpl(hdr_lump);
+ sr_error:
+	return -1;
+}
+
+
+
+int unixsock_t_reply(str* msg)
+{
+	int ret;
+	struct cell *trans;
+	static char new_headers[MAX_HEADER];
+	str code, reason, transid, headers, body, to_tag;
+	unsigned int hash_index, label, icode;
+
+	headers.s = new_headers;
+	headers.len = MAX_HEADER;
+
+	if (unixsock_read_line(&code, msg) != 0) {
+		unixsock_reply_asciiz("400 Reason code expected\n");
+		goto err;
+	}
+
+	icode = str2s(code.s, code.len, &ret);
+	if (ret) {
+		unixsock_reply_printf("400 Reason code has wrong format\n");
+		goto err;
+	}
+
+	if (unixsock_read_line(&reason, msg) != 0) {
+		unixsock_reply_asciiz("400 Reason phrase expected\n");
+		goto err;
+	}
+
+	if (unixsock_read_line(&transid, msg) != 0) {
+		unixsock_reply_asciiz("400 Transaction ID expected\n");
+		goto err;
+	}
+
+	if (parse_transid(&transid, &hash_index, &label) < 0) {
+		unixsock_reply_asciiz("400 Error while parsing transaction ID\n");
+		goto err;
+	}
+
+	if (unixsock_read_line(&to_tag, msg) != 0) {
+		unixsock_reply_asciiz("400 To tag expected\n");
+		goto err;
+	}
+
+	     /* read the new headers */
+	if (unixsock_read_lineset(&headers, msg) < 0) {
+		unixsock_reply_asciiz("400 Error while reading new headers\n");
+		goto err;
+	}
+
+	DBG("lineset: %.*s\n", headers.len, headers.s);
+	     
+	/*  body can be empty ... */
+	if (unixsock_read_body(&body, msg) < 0) {
+		unixsock_reply_asciiz("400 Error while reading body\n");
+		goto err;
+	}
+
+	DBG("body: %.*s\n", body.len, body.s);
+	
+	if (t_lookup_ident(&trans, hash_index, label) < 0) {
+		LOG(L_ERR,"unixsock_t_reply: lookup failed\n");
+		unixsock_reply_asciiz("481 No such transaction\n");
+		goto err;
+	}
+
+	     /* it's refcounted now, t_reply_with body unrefs for me -- I can 
+	      * continue but may not use T anymore  
+	      */
+	ret = send_reply(trans, icode, &reason, &body, &headers, &to_tag);
+	if (ret < 0) {
+		LOG(L_ERR, "unixsock_t_reply: reply failed\n");
+		unixsock_reply_asciiz("500 Reply failed\n");
+		goto err;
+	}
+
+	unixsock_reply_asciiz("200 Succeeded\n");
+	unixsock_reply_send();
+	return 1;
+
+ err:
+	unixsock_reply_send();
+	return -1;
+}

+ 2 - 0
modules/tm/t_reply.h

@@ -143,5 +143,7 @@ int t_pick_branch(int inc_branch, int inc_code, struct cell *t, int *res_code);
 
 int fifo_t_reply( FILE *stream, char *response_file );
 
+int unixsock_t_reply(str* msg);
+
 #endif
 

+ 11 - 0
modules/tm/tm.c

@@ -99,6 +99,7 @@
 #include "t_reply.h"
 #include "uac.h"
 #include "uac_fifo.h"
+#include "uac_unixsock.h"
 #include "t_fwd.h"
 #include "t_lookup.h"
 #include "t_stats.h"
@@ -497,6 +498,16 @@ static int mod_init(void)
 		return -1;
 	}
 
+	if (unixsock_register_cmd("t_uac", unixsock_uac) < 0) {
+		LOG(L_CRIT, "cannot register t_uac with the unix server\n");
+		return -1;
+	}
+
+	if (unixsock_register_cmd("t_reply", unixsock_t_reply) < 0) {
+		LOG(L_CRIT, "cannot register t_reply with the unix server\n");
+		return -1;
+	}
+
 	/* building the hash table*/
 	if (!init_hash_table()) {
 		LOG(L_ERR, "ERROR: mod_init: initializing hash_table failed\n");