[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;
}