[PATCH] problems with HTTPS and base support for per message billing.

"Oded Arbel" <[email protected]>
Newsgroups gmane.comp.mobile.kannel.devel
Message-ID <[email protected]>
Hi list.

Here are two patches that were useful to me, and I hope that will be
considered for submission :

- HTTPS : I had a problem with a broken HTTPS server implementation
(that I had to get Kannel to connect to), which sometimes would not
complete the SSL handshake but will send a FIN packet in the middle of
the setup. I've read something about it in OpenSSL documentation, but
its said there that OpenSSL should detect this and return with an error.
apparently (from many tests) this does not happen : when SSL_connect()
gets that packet it just ignores it and continues to wait for the SSL
handshake completion - which hangs for ever. 
The simple work around that I submit here will simply set the socket to
non-blocking state early, and then loop around the SSL_connect() until
it either succeeds in connecting or timesout. currently the timeout is
hardcoded as 30 seconds (which I think should be reasonable for all
purposes). I tried to look for a fast way to get it configurable, but
didn't find any quick hack - so I left it be.

- Billing : I needed to get a per message billing information into
Kannel, so I added a "billing" parameter to the sendsms call and a
billing integer to the SMS message data structure. this was really a
search-and-replace kind of hack, into a code I don't fully understand,
so I hope I didn't brake anything.

Both patches are deployed and "works for me", and while I understand
that those are not high priority  problems for most users, I will be
grateful if the patches are incorporated into the CVS (will save me work
when I update from CVS ;-)

Cheers

--
Oded Arbel
m-Wise Inc.
[email protected]
(972)-67-340014
(972)-9-9581711 (ext: 116)

::..
Juall's Law on Nice Guys:
Nice guys don't always finish last; sometimes they don't finish.
Sometimes they don't even get a chance to start!  



 <<billing.patch>>  <<https.patch>>
billing.patch (application/octet-stream, 10 KB)
diff -ru kannel-dev/gateway/gw/msg-decl.h gateway/gw/msg-decl.h
--- kannel-dev/gateway/gw/msg-decl.h	2002-03-07 12:37:33.000000000 +0200
+++ gateway/gw/msg-decl.h	2002-05-13 20:03:28.000000000 +0300
@@ -43,6 +43,7 @@
 		INTEGER(pid);
 		INTEGER(alt_dcs);
 		OCTSTR(charset);
+                INTEGER(billing);
 	})
 
 MSG(ack,
diff -ru kannel-dev/gateway/gw/smsbox.c gateway/gw/smsbox.c
--- kannel-dev/gateway/gw/smsbox.c	2002-05-05 10:57:31.000000000 +0300
+++ gateway/gw/smsbox.c	2002-05-13 20:16:13.000000000 +0300
@@ -233,7 +233,8 @@
     receiver->msg->sms.time = (time_t) -1;
     receiver->msg->sms.smsc_id = octstr_duplicate(msg->sms.smsc_id);
     receiver->msg->sms.dlr_url = NULL;
     receiver->msg->sms.dlr_mask = msg->sms.dlr_mask; 
+    receiver->msg->sms.billing = 0;
     	/* to remember if it's a DLR http get */
     
     receiver->trans = trans;
@@ -291,7 +292,7 @@
 				      int *coding, int *compress, 
 				      int *validity, int *deferred, 
 				      int *dlr_mask, Octstr **dlr_url, 
-				      Octstr **account, int *pid, int *alt_dcs)
+				      Octstr **account, int *pid, int *alt_dcs, int *billing)
 {
     Octstr *name, *val;
     long l;
@@ -299,7 +300,7 @@
     *dlr_mask = 0;
     *dlr_url = NULL;
     *mclass = *mwi = *coding = *compress = *validity = 
-	*deferred = *pid = *alt_dcs = 0;
+	*deferred = *pid = *alt_dcs = *billing = 0;
     for(l=0; l<list_len(headers); l++) {
 	http_header_get(headers, l, &name, &val);
 
@@ -376,6 +377,9 @@
 	else if (octstr_case_compare(name, octstr_imm("X-Kannel-DLR-Mask")) == 0) {
     	    sscanf(octstr_get_cstr(val),"%d", dlr_mask);
 	}
+	else if (octstr_case_compare(name, octstr_imm("X-Kannel-Billing")) == 0) {
+    	    sscanf(octstr_get_cstr(val),"%d", billing);
+	}
 	octstr_destroy(name);
 	octstr_destroy(val);
     }
@@ -430,7 +434,7 @@
                                   int *coding, int *compress, 
                                   int *validity, int *deferred,
                                   int *dlr_mask, Octstr **dlr_url,
-                                  Octstr **account, int *pid, int *alt_dcs)
+                                  Octstr **account, int *pid, int *alt_dcs, int* billing)
 {                                    
 
 /*
@@ -451,6 +455,7 @@
  *       <alt-dcs>.</alt-dcs>
  *     </dcs>
  *     <pid>..</pid>
+ *     <billing>.</billing>
  *     <statusrequest>
  *       <dlr-mask>..</dlr-mask>
  *       <dlr-url>...</dlr-url>
@@ -473,7 +478,7 @@
     *dlr_mask = 0;
     *dlr_url = NULL;
     *mclass = *mwi = *coding = *compress = *validity = 
-	*deferred = *pid = *alt_dcs = 0;
+	*deferred = *pid = *alt_dcs = *billing = 0;
 
     debug("sms", 0, "XMLParsing: XML: <%s>", octstr_get_cstr(*body));
 
@@ -618,6 +623,14 @@
 	O_DESTROY(tmp);
     }
 
+    /* billing */
+    get_tag(*body, octstr_imm("billing"), &tmp, 0, 0);
+    if(tmp) {
+	if(octstr_parse_long(&tmplong, tmp, 0, 10) != -1)
+	    *billing = tmplong;
+	O_DESTROY(tmp);
+    }
+
     /* text */
     text = NULL;
     get_tag(*body, octstr_imm("ud"), &text, 0, 0);
@@ -639,7 +652,7 @@
 			 Octstr *from, Octstr *to, Octstr *udh, 
 			 int mclass, int mwi, int coding, int compress,
 			 int validity, int deferred,
-			 Octstr *dlr_url, int dlr_mask, int pid, int alt_dcs,
+			 Octstr *dlr_url, int dlr_mask, int pid, int alt_dcs, int billing,
 			 Octstr *smsc)
 {    
     msg->sms.msgdata = replytext;
@@ -761,6 +774,12 @@
 	    warning(0, "Tried to change dlr_mask to '%d', denied.",
 		    dlr_mask);
     }
+    if (billing) {
+        if (urltrans_accept_x_kannel_headers(trans))
+	    msg->sms.billing = billing;	
+	else
+	    warning(0, "Tried to set billing field, denied.");
+    }
 }
 
 
@@ -783,7 +802,7 @@
     Octstr *smsc;
     int dlr_mask;
     int octets;
-    int mclass, mwi, coding, compress, pid, alt_dcs;
+    int mclass, mwi, coding, compress, pid, alt_dcs, billing;
     int validity, deferred;
     
     dlr_mask = 0;
@@ -803,7 +822,7 @@
     	get_receiver(id, &msg, &trans);
 
     	from = to = udh = smsc = NULL;
-	octets = mclass = mwi = coding = compress = pid = alt_dcs = 0;
+	octets = mclass = mwi = coding = compress = pid = alt_dcs = billing = 0;
 	validity = deferred = 0;
 	account = NULL;
 	
@@ -820,7 +839,7 @@
 					  NULL, NULL, &smsc, &mclass, &mwi, 
 					  &coding, &compress, &validity, 
 					  &deferred, &dlr_mask, &dlr_url, 
-					  &account, &pid, &alt_dcs);
+					  &account, &pid, &alt_dcs, &billing);
 	    } else if (octstr_case_compare(type, text_plain) == 0) {
 		replytext = octstr_duplicate(reply_body);
                 octstr_destroy(reply_body);
@@ -830,7 +849,7 @@
 					  NULL, NULL, &smsc, &mclass, &mwi, 
 					  &coding, &compress, &validity, 
 					  &deferred, &dlr_mask, &dlr_url, 
-					  &account, &pid, &alt_dcs);
+					  &account, &pid, &alt_dcs, &billing);
 	    } else if (octstr_case_compare(type, text_xml) == 0) {
 		replytext = octstr_duplicate(reply_body);
 		octstr_destroy(reply_body); 
@@ -838,7 +857,7 @@
 		get_x_kannel_from_xml(mt_reply, &type, &replytext, reply_headers, &from, &to, &udh,
 				NULL, NULL, &smsc, &mclass, &mwi, &coding,
 				&compress, &validity, &deferred,
-				&dlr_mask, &dlr_url, &account, &pid, &alt_dcs);
+				&dlr_mask, &dlr_url, &account, &pid, &alt_dcs, &billing);
 	    } else if (octstr_case_compare(type, octet_stream) == 0) {
 		replytext = octstr_duplicate(reply_body);
                 octstr_destroy(reply_body);
@@ -848,7 +867,7 @@
 					  NULL, NULL, &smsc, &mclass, &mwi, 
 					  &coding, &compress, &validity, 
 					  &deferred, &dlr_mask, &dlr_url, 
-					  &account, &pid, &alt_dcs);
+					  &account, &pid, &alt_dcs, &billing);
 	    } else {
 		replytext = octstr_duplicate(reply_couldnotrepresent); 
 	    }
@@ -863,7 +882,7 @@
 
 	fill_message(msg, trans, replytext, octets, from, to, udh, mclass,
 			mwi, coding, compress, validity, deferred, dlr_url, 
-			dlr_mask, pid, alt_dcs, smsc);
+			dlr_mask, pid, alt_dcs, billing, smsc);
 
     	if (final_url == NULL)
 	    final_url = octstr_imm("");
@@ -1088,7 +1107,14 @@
 	    	octstr_get_cstr(os));
 	    octstr_destroy(os);
 	}
-	http_start_request(caller, pattern, request_headers, 
+	if(msg->sms.billing) {
+	    Octstr *os;
+	    os = octstr_format("%d",msg->sms.billing);
+	    http_header_add(request_headers, "X-Kannel-Billing",
+	    	octstr_get_cstr(os));
+	    octstr_destroy(os);
+	}
+	http_start_request(caller, pattern, request_headers,
  			   msg->sms.msgdata, 1, id, NULL);
 	octstr_destroy(pattern);
 	http_destroy_headers(request_headers);
@@ -1168,6 +1194,11 @@
 	    OCTSTR_APPEND_XML_NUMBER(xml, "pid", msg->sms.pid);
 	}
 
+	/* billing */
+	if(msg->sms.billing != 0) {
+	    OCTSTR_APPEND_XML_NUMBER(xml, "billing", msg->sms.billing);
+	}
+
 	/* dcs */
 	{
 	    tmp = octstr_create("");
@@ -1530,7 +1561,7 @@
 				 int mclass, int mwi, int coding, int compress, 
 				 int validity, int deferred, 
 				 int *status, int dlr_mask, Octstr *dlr_url, 
-				 Octstr *account, int pid, int alt_dcs)
+				 Octstr *account, int pid, int alt_dcs, int billing)
 {				     
     Msg *msg = NULL;
     Octstr *newfrom, *returnerror, *receiv;
@@ -1720,6 +1751,12 @@
     }
     msg->sms.deferred = deferred;
 
+    if ( billing < 0 ) {
+	returnerror = octstr_create("Billing field misformed, rejected");
+	goto fielderror;
+    }
+    msg->sms.billing = billing;
+
     /* new smsc-id argument - we should check this one, if able,
        but that's advanced logics -- Kalle */
     
@@ -1925,7 +1962,7 @@
     Octstr *account = NULL;
     int	dlr_mask = 0;
     Octstr *dlr_mask_string;
-    int mclass, mwi, coding, compress, validity, deferred, pid, alt_dcs;
+    int mclass, mwi, coding, compress, validity, deferred, pid, alt_dcs, billing;
    
     /* check the username and password */
     t = authorise_user(args, client_ip);
@@ -1944,13 +1981,14 @@
     dlr_url = http_cgi_variable(args, "dlrurl");
     dlr_mask_string = http_cgi_variable(args, "dlrmask");
 
+
     if(dlr_mask_string != NULL)
         sscanf(octstr_get_cstr(dlr_mask_string),"%d",&dlr_mask);
     else
     	dlr_mask = 0;
 
     mclass = mwi = coding = compress = validity = 
-	deferred = pid = alt_dcs = 0;
+	deferred = pid = alt_dcs = billing = 0;
 
     tmp_string = NULL;
     tmp_string = http_cgi_variable(args, "flash");
@@ -2000,6 +2038,11 @@
         sscanf(octstr_get_cstr(tmp_string),"%d", &deferred);
     }
 
+    tmp_string = NULL;
+    tmp_string = http_cgi_variable(args, "billing");
+    if(tmp_string != NULL)
+        sscanf(octstr_get_cstr(tmp_string),"%d", &billing);
+
     /*
      * we expect cgi var text to be defined, even if it may be
      * empty to allow empty messages, st.
@@ -2019,7 +2062,7 @@
     return smsbox_req_handle(t, client_ip, from, to, text, charset, udh, 
 			     smsc, mclass, mwi, coding, compress, validity, 
 			     deferred, status, dlr_mask, dlr_url, account,
-			     pid, alt_dcs);
+			     pid, alt_dcs, billing);
     
 }
 
@@ -2038,7 +2081,7 @@
     Octstr *dlr_url;
     Octstr *account;
     int dlr_mask = 0;
-    int mclass, mwi, coding, compress, validity, deferred, pid, alt_dcs;
+    int mclass, mwi, coding, compress, validity, deferred, pid, alt_dcs, billing;
  
     from = to = user = pass = udh = smsc = dlr_url = account = NULL;
    
@@ -2051,12 +2094,12 @@
 	get_x_kannel_from_xml(mt_push, &type, &body, headers, &from, &to, &udh,
 		       	&user, &pass, &smsc, &mclass, &mwi, &coding,
 		       	&compress, &validity, &deferred,
-		       	&dlr_mask, &dlr_url, &account, &pid, &alt_dcs);
+		       	&dlr_mask, &dlr_url, &account, &pid, &alt_dcs, &billing);
     } else {
 	get_x_kannel_from_headers(headers, &from, &to, &udh,
 			      &user, &pass, &smsc, &mclass, &mwi, &coding,
 			      &compress, &validity, &deferred, 
-			      &dlr_mask, &dlr_url, &account, &pid, &alt_dcs);
+			      &dlr_mask, &dlr_url, &account, &pid, &alt_dcs, &billing);
     }
 
     /* check the username and password */
@@ -2096,7 +2139,7 @@
 	    ret = smsbox_req_handle(t, client_ip, from, to, body, charset,
 				    udh, smsc, mclass, mwi, coding, compress, 
 				    validity, deferred, status, 
-				    dlr_mask, dlr_url, account, pid, alt_dcs);
+				    dlr_mask, dlr_url, account, pid, alt_dcs, billing);
 
 	octstr_destroy(type);
 	octstr_destroy(charset);
https.patch (application/octet-stream, 2.3 KB)
diff -ru kannel-dev/gateway/gwlib/conn.c gateway/gwlib/conn.c
--- kannel-dev/gateway/gwlib/conn.c	2002-02-21 11:41:38.000000000 +0200
+++ gateway/gwlib/conn.c	2002-05-09 12:15:24.000000000 +0300
@@ -45,6 +45,7 @@
  * conn_register.
  */
 #define DEFAULT_OUTPUT_BUFFERING 0
+#define SSL_CONN_TIMEOUT         30
 
 struct Connection
 {
@@ -361,6 +362,8 @@
 {
     Connection *ret;
     int SSL_ret;
+    int connected = 0;
+    time_t timeout;
 
     ret = conn_open_tcp(host, port, our_host);
 
@@ -391,24 +394,48 @@
     ERR_clear_error();
 
     /*
-     * make the socket blocking while we do SSL_connect
+     * make the socket is non-blocking while we do SSL_connect
      */
-    if (socket_set_blocking(ret->fd, 1) < 0) {
+    if (socket_set_blocking(ret->fd, 0) < 0) {
 	goto error;
     }
-    
-    SSL_ret = SSL_connect(ret->ssl);
-    
+
+    /* record current time */
+    timeout = time(NULL);
+
+    while(!connected && (timeout + SSL_CONN_TIMEOUT > time(NULL))) {
+        /* Attempt to connect as long as the timeout hasn't run down */
+        SSL_ret = SSL_connect(ret->ssl);
+        switch(SSL_get_error(ret->ssl,SSL_ret)) {
+            case SSL_ERROR_WANT_READ:
+            case SSL_ERROR_WANT_WRITE:
+                /* non-blocking socket wants more time to read or write */
+                gwthread_sleep(0.01F);
+                continue;
+            default:
+                /* we're connected to the server successfuly */
+                connected++;
+        }
+    }
+
+    if (!connected) {
+        /* connection timedout - this probably means that something is terrible wrong */
+	int SSL_error = SSL_get_error (ret->ssl, SSL_ret);
+         error(0,"SSL connection timedout: OpenSSL error (probably not useful) %d: %s",
+               SSL_error, ERR_error_string(SSL_error, NULL));
+        goto error;
+    }
+
     /*
      * restore the non-blocking state
-     */
+     *
     if (socket_set_blocking(ret->fd, 0) < 0) {
 	goto error;
     }
-    
+     */
     if (SSL_ret != 1) {
-	int SSL_error = SSL_get_error (ret->ssl, SSL_ret); 
-	error(0, "SSL connect failed: OpenSSL error %d: %s", 
+	int SSL_error = SSL_get_error (ret->ssl, SSL_ret);
+	error(0, "SSL connect failed: OpenSSL error %d: %s",
 	      SSL_error, ERR_error_string(SSL_error, NULL));
 	goto error;
     }
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.