ソースを参照

uac changed to include From parameter
dlg_t typedef created
fifo_uac now excpects a request to be terminated with ".<EoL>"

Jiri Kuthan 23 年 前
コミット
c430ed7b49
10 ファイル変更106 行追加30 行削除
  1. 62 10
      fifo_server.c
  2. 2 0
      fifo_server.h
  3. 2 2
      modules/tm/t_dlg.c
  4. 3 1
      modules/tm/t_dlg.h
  5. 12 4
      modules/tm/t_msgbuilder.c
  6. 1 1
      modules/tm/t_msgbuilder.h
  7. 9 5
      modules/tm/uac.c
  8. 4 1
      modules/tm/uac.h
  9. 9 4
      scripts/sc
  10. 2 2
      test/transaction.fifo

+ 62 - 10
fifo_server.c

@@ -1,11 +1,31 @@
 /*
  * $Id$
  *
- * simple UAC for things such as SUBSCRIBE or SMS gateway;
- * no authentication and other UAC features -- just send
- * a message, retransmit and await a reply; forking is not
- * supported during client generation, in all other places
- * it is -- adding it should be simple
+ * Fifo server is a very powerful tool used to access easily
+ * ser's internals via textual interface, similarly to
+ * how internals of many operating systems are accessible
+ * via the proc file system. This might be used for
+ * making ser do things for you (such as initiating new
+ * transaction from webpages) or inspect server's health.
+ * 
+ * FIFO server allows new functionality to be registered
+ * with it -- thats what register_fifo_cmd is good for.
+ * Remember, the initialization must take place before
+ * forking; best in init_module functions. When a function
+ * is registered, it can be always evoked by sending its
+ * name prefixed by colon to the FIFO.
+ *
+ * There are few commands already implemented in core.
+ * These are 'uptime' for looking at how long the server
+ * is alive and 'print' for debugging purposes.
+ *
+ * Every command sent to FIFO must be sent atomically to
+ * avoid intermixing with other commands and MUST be
+ * terminated by empty line so that the server is to able
+ * to find its end if it does not understand the command.
+ *
+ * File test/transaction.fifo illustrates example of use
+ * of t_uac command (part of TM module).
  */
 
 #include <stdlib.h>
@@ -29,7 +49,8 @@
 
 /* FIFO server vars */
 char *fifo=0; /* FIFO name */
-int fifo_mode=S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
+int fifo_mode=S_IRUSR | S_IWUSR | S_IRGRP | 
+	S_IWGRP | S_IROTH | S_IWOTH;
 pid_t fifo_pid;
 /* file descriptors */
 static int fifo_read=0;
@@ -136,7 +157,8 @@ int read_eol( FILE *stream )
 	}
 	return 1;
 }
-	
+
+/* read from input until empty line is encountered */	
 int read_line_set(char *buf, int max_len, FILE *fifo, int *len)
 {
 	int set_len;
@@ -164,6 +186,34 @@ int read_line_set(char *buf, int max_len, FILE *fifo, int *len)
 	}
 }
 
+/* read from input until line with only dot in it is encountered */
+int read_body(char *buf, int max_len, FILE *fifo, int *len)
+{
+	int set_len;
+	char *c;
+	int line_len;
+
+	c=buf;set_len=0;
+	while(1) {
+		if (!read_line(c,max_len,fifo,&line_len)) {
+			LOG(L_ERR, "ERROR: fifo_server: line expected\n");
+			return 0;
+		}
+		/* end encountered ... return */
+		if (line_len==1 && *c=='.') {
+			*len=set_len;
+			return 1;
+		}
+		max_len-=line_len; c+=line_len; set_len+=line_len;
+		if (max_len<CRLF_LEN) {
+			LOG(L_ERR, "ERROR: fifo_server: no place for CRLF\n");
+			return 0;
+		}
+		memcpy(c, CRLF, CRLF_LEN);
+		max_len-=CRLF_LEN; c+=CRLF_LEN; set_len+=CRLF_LEN;
+	}
+}
+
 static char *trim_filename( char * file )
 {
 	int prefix_len, fn_len;
@@ -311,10 +361,12 @@ int open_fifo_server()
 	}
 	DBG("TM: open_uac_fifo: opening fifo...\n");
 	if ((mkfifo(fifo, fifo_mode)<0) && (errno!=EEXIST)) {
-		LOG(L_ERR, "ERROR: open_fifo_server; can't create FIFO: %s\n",
-			strerror(errno));
+		LOG(L_ERR, "ERROR: open_fifo_server; can't create FIFO: "
+			"%s (mode=%d)\n",
+			strerror(errno), fifo_mode);
 		return -1;
-	}
+	} 
+	DBG("DEBUG: fifo %s opened, mode=%d\n", fifo, fifo_mode );
 	time(&up_since);
 	process_no++;
 	fifo_pid=fork();

+ 2 - 0
fifo_server.h

@@ -31,6 +31,8 @@ int read_line( char *b, int max, FILE *stream, int *read );
 int read_eol( FILE *stream );
 /* consume a set of EoL-terminated lines terminated by an additional EoL */
 int read_line_set(char *buf, int max_len, FILE *fifo, int *len);
+/* consume a set of EoL-terminated lines terminated by a single dot line */
+int read_body(char *buf, int max_len, FILE *fifo, int *len);
 
 int open_fifo_server();
 

+ 2 - 2
modules/tm/t_dlg.c

@@ -5,7 +5,7 @@
 
 #include "t_dlg.h"
 
-static struct dialog *dlg=0;
+dlg_t dlg=0;
 
 int t_newdlg( struct sip_msg *msg )
 {
@@ -14,7 +14,7 @@ int t_newdlg( struct sip_msg *msg )
 	return 0;
 }
 
-struct dialog *t_getdlg() {
+dlg_t t_getdlg() {
 	return dlg;
 }
 

+ 3 - 1
modules/tm/t_dlg.h

@@ -12,7 +12,9 @@ struct dialog {
 	int place_holder;
 };
 
+typedef struct dialog *dlg_t;
+
 int t_newdlg( struct sip_msg *msg );
-struct dialog *t_getdlg() ;
+dlg_t t_getdlg() ;
 
 #endif

+ 12 - 4
modules/tm/t_msgbuilder.c

@@ -143,7 +143,7 @@ error:
 
 
 
-char *build_uac_request(  str msg_type, str dst,
+char *build_uac_request(  str msg_type, str dst, str from,
     	str headers, str body, int branch, 
 		struct cell *t, int *len)
 {
@@ -158,10 +158,18 @@ char *build_uac_request(  str msg_type, str dst,
 	char branch_buf[MAX_BRANCH_PARAM_LEN];
 	int branch_len;
 
-	static int from_len=0;
+	int from_len;
+	char *from_str;
 
 	buf=0;
-	if (from_len==0) from_len=strlen(uac_from);
+
+	if (from.len) {
+		from_len=from.len;
+		from_str=from.s;
+	} else {
+		from_len=strlen(uac_from);
+		from_str=uac_from;
+	}
 	
 	*len=SIP_VERSION_LEN+msg_type.len+2/*spaces*/+CRLF_LEN+
 		dst.len;
@@ -231,7 +239,7 @@ char *build_uac_request(  str msg_type, str dst,
 			CRLF_LEN+FROM_LEN);
 	}
 	t->from.s=w-FROM_LEN; t->from.len=FROM_LEN+from_len+FROMTAG_LEN+MD5_LEN;
-	memapp( w, uac_from, from_len );
+	memapp( w, from_str, from_len );
 	memapp( w, FROMTAG, FROMTAG_LEN );
 	memapp( w, from_tag, MD5_LEN );
 	memapp( w, CRLF, CRLF_LEN );

+ 1 - 1
modules/tm/t_msgbuilder.h

@@ -49,7 +49,7 @@
 char *build_local(struct cell *Trans, unsigned int branch,
 	unsigned int *len, char *method, int method_len, str *to);
 
-char *build_uac_request(  str msg_type, str dst,
+char *build_uac_request(  str msg_type, str dst, str from,
 	str headers, str body, int branch,
 	struct cell *t, int *len);
 

+ 9 - 5
modules/tm/uac.c

@@ -97,8 +97,9 @@ void generate_callid() {
 
 
 int t_uac( str *msg_type, str *dst, 
-	str *headers, str *body, transaction_cb completion_cb,
-	void *cbp, struct dialog *dlg)
+	str *headers, str *body, str *from, 
+	transaction_cb completion_cb, void *cbp, 
+	dlg_t dlg)
 {
 
 	struct cell *new_cell;
@@ -110,6 +111,7 @@ int t_uac( str *msg_type, str *dst,
 	union sockaddr_union to;
 	struct socket_info* send_sock;
 	struct retr_buf *request;
+	str dummy_from;
 
 	/* be optimist -- assume success for return value */
 	ret=1;
@@ -155,7 +157,8 @@ int t_uac( str *msg_type, str *dst,
 	request->to=to;
 	request->send_sock=send_sock;
 
-	buf=build_uac_request(  *msg_type, *dst, *headers, *body, branch,
+	if (from) dummy_from=*from; else { dummy_from.s=0; dummy_from.len=0; }
+	buf=build_uac_request(  *msg_type, *dst, dummy_from, *headers, *body, branch,
 		new_cell /* t carries hash_index, label, md5, uac[].send_sock and
 		     other pieces of information needed to print a message*/
 		, &req_len );
@@ -270,7 +273,7 @@ int fifo_uac( FILE *stream, char *response_file )
 		}
 		DBG("DEBUG: fifo_uac: header: %.*s\n", sh.len, header );
 		/* and eventually body */
-		if (!read_line_set(body, MAX_BODY, stream, &sb.len)) {
+		if (!read_body(body, MAX_BODY, stream, &sb.len)) {
 			LOG(L_ERR, "ERROR: fifo_uac: body expected\n");
 			return -1;
 		}
@@ -292,7 +295,8 @@ int fifo_uac( FILE *stream, char *response_file )
 		   will not be triggered and no feedback will be printed
 		   to shmem_file
 		*/
-		t_uac(&sm,&sd,&sh,&sb,fifo_callback,shmem_file,0 /* no dialog */);
+		t_uac(&sm,&sd,&sh,&sb, 0 /* default from */,
+			fifo_callback,shmem_file,0 /* no dialog */);
 		return 1;
 
 	}

+ 4 - 1
modules/tm/uac.h

@@ -29,7 +29,7 @@ void uac_child_init( int rank );
 void generate_callid();
 
 typedef int (*tuac_f)(str *msg_type, str *dst, str *headers,str *body,
-	transaction_cb completion_cb );
+	str *from, transaction_cb completion_cb );
 
 /* transactional UAC; look for an example of usage at fifo_uac */
 int t_uac( 
@@ -42,6 +42,9 @@ int t_uac(
 	   generated by UAC: To, Content_length, CSeq, Call-ID, Via, From
 		(From is taken from config option)
 	*/
+	str *from, /* optional value to be included in From *without* tag;
+	              if 0, then config value uac_from will be used
+	           */
 	str *headers, 
 	/* body of the message if any */
 	str *body,

+ 9 - 4
scripts/sc

@@ -14,9 +14,9 @@ SER_FIFO=/tmp/ser_fifo
 WATCH_PERIOD=2
 
 # SQL config
-SQL_DB=csps107
+SQL_DB=ser
 SQL_HOST=dbhost
-SQL_USER=csps
+SQL_USER=ser
 
 # the read-only user for whom password may be stored here
 RO_USER=serro
@@ -29,7 +29,12 @@ SER='sr'
 
 # ACL name verification
 VERIFY_ACL=1
-ACL_GROUPS="local ld int"
+ACL_GROUPS="local ld int voicemail free-pstn"
+
+# expiration time for alias table
+if [ -z "$FOREVER" ]; then 
+	FOREVER='2020-05-28 21:32:15'
+fi
 
 #### SQL names
 
@@ -187,7 +192,7 @@ ser_alias() {
 				($A_USER_COLUMN, $A_CONTACT_COLUMN, $A_EXPIRES_COLUMN, \
 				$A_Q_COLUMN, $A_CALLID_COLUMN, $A_CSEQ_COLUMN, \
 				$A_LAST_MODIFIED_COLUMN) \
-				values ( '$2', '$3', '2099-05-28 21:32:15', \
+				values ( '$2', '$3', '$FOREVER', \
 				'1.00', 'call-id-for-ever', '1',
 				now() );"
 			sql_query "$QUERY"

+ 2 - 2
test/transaction.fifo

@@ -1,6 +1,6 @@
 :t_uac:hh
 MESSAGE
-sip:jirim@iptel.org
+sip:gh@iptel.org
 foo: bar
 x: y
 p_header: p_value
@@ -8,5 +8,5 @@ Contact: <sip:195.37.77.100:9>
 Content-Type: text/plain; charset=UTF-8;msgr=WAAtAE0ATQBTAC0ASQBNAC0ARgBvAHIAbQBhAHQAOgAgAEYATgA9AE0AUwAlADIAMABTAGgAZQBsAGwAJQAyADAARABsAGcAOwAgAEUARgA9ADsAIABDAE8APQAwADsAIABDAFMAPQAwADsAIABQAEYAPQAwAA0ACgANAAoA
 
 I love you man!!!!
-
+.