Hi, it may be that this discussion has been already active - if so, my 
apologies for repetition. 

I have encountered a Kannel instance, where Kannel retries to send an MT 
several times per second without any limitations. SMSC rejects the MT request, 
and the connector marks the failure with SMSCCONN_FAILED_TEMPORARILY. 

This error is found in customized SMSC connector, that uses sessions and SOAP. 
The rejection (NACK) code is "Session error", which then calls the 
smsc-function bb_smscconn_send_failed (see below). So there are some code that 
is not part of Kannel, but this retry limitation is implemented in this 
function that forms part of Kannel, and therefore it should work also with 
customized SMSC connectors.

So, the max_retry does not work, or delay between the retries - it seems that 
in some special occasion Kannel loses the control.

I have analyzed some part of the code, and found this:

in gw/bb_smscconn.c, lines 288- (in version 1.4.3) there is the following code:

void bb_smscconn_send_failed(SMSCConn *conn, Msg *sms, int reason, Octstr 
*reply)
{
    if (sms->sms.split_parts != NULL) {
        handle_split(conn, sms, reason);
        octstr_destroy(reply);
        return;
    }
    
    switch (reason) {
    case SMSCCONN_FAILED_TEMPORARILY:
        /*
         * Check if SMSC link alive and if so increase resend_try and set 
resend_time.
         * If SMSC link is not active don't increase resend_try and don't set 
resend_time
         * because we don't want to delay messages because of connection broken.
         */
       if (conn && smscconn_status(conn) == SMSCCONN_ACTIVE) {
            /*
             * Check if sms_resend_retry set and this msg has exceeded a limit 
also
             * honor "single shot" with sms_resend_retry set to zero.
             */
           if (sms_resend_retry >= 0 && sms->sms.resend_try >= 
sms_resend_retry) {
               warning(0, "Maximum retries for message exceeded, discarding 
it!");
               bb_smscconn_send_failed(NULL, sms, SMSCCONN_FAILED_DISCARDED, 
                                       octstr_create("Retries Exceeded"));
               break;
           }
           sms->sms.resend_try = (sms->sms.resend_try > 0 ? sms->sms.resend_try 
+ 1 : 1);
           time(&sms->sms.resend_time);
       }
       gwlist_produce(outgoing_sms, sms);
       break;

In this code, the limitation of retries only works if the status of the 
connection is SMSCCONN_ACTIVE. But maybe the status of the connection can be 
different to SMSCCONN_ACTIVE, but still alive. If so, we would enter to a loop 
of unlimited retries. 

I haven't been able to test what is the state of the connection when this error 
happens. From the header file you can see that the possible status are:

    SMSCCONN_CONNECTING,
    SMSCCONN_ACTIVE,
    SMSCCONN_ACTIVE_RECV,
    SMSCCONN_RECONNECTING,
    SMSCCONN_DISCONNECTED,

and at the moment the retry counter is working only with one of them. For 
example, if the status is CONNECTING or ACTIVE_RECV, or RECONNECTING, then the 
retry limitation would not work. 

So I think that in this condition other status should be taken into account too.

Any opinions?


Best regards,

Antti

Reply via email to