Index: gwlib/cfg.def =================================================================== --- gwlib/cfg.def (revision 28) +++ gwlib/cfg.def (working copy) @@ -119,6 +119,8 @@ OCTSTR(ssl-server-key-file) OCTSTR(ssl-trusted-ca-file) OCTSTR(dlr-storage) + OCTSTR(dlr-retry-count) + OCTSTR(dlr-retry-delay) OCTSTR(maximum-queue-length) OCTSTR(sms-incoming-queue-limit) OCTSTR(sms-outgoing-queue-limit) Index: gw/dlr.c =================================================================== --- gw/dlr.c (revision 27) +++ gw/dlr.c (working copy) @@ -228,6 +228,7 @@ { CfgGroup *grp; Octstr *dlr_type; + long retry_delay; /* check which DLR storage type we are using */ grp = cfg_get_single_group(cfg, octstr_imm("core")); @@ -269,6 +270,14 @@ /* check needed function pointers */ if (handles->dlr_add == NULL || handles->dlr_get == NULL || handles->dlr_remove == NULL) panic(0, "DLR: storage type '%s' don't implement needed functions", octstr_get_cstr(dlr_type)); + + if (cfg_get_integer(&handles->retry_count, grp, octstr_imm("dlr-retry-count")) == -1) { + handles->retry_count = 1; + } + if (cfg_get_integer(&retry_delay, grp, octstr_imm("dlr-retry-delay")) == -1) { + retry_delay = 0; + } + handles->retry_delay = (double)retry_delay/1000.0; /* get info from storage */ info(0, "DLR using storage type: %s", handles->type); @@ -364,6 +373,7 @@ { Msg *msg = NULL; struct dlr_entry *dlr = NULL; + int retry = 0; if(octstr_len(smsc) == 0) { warning(0, "DLR[%s]: Can't find a dlr without smsc-id", dlr_type()); @@ -377,13 +387,30 @@ debug("dlr.dlr", 0, "DLR[%s]: Looking for DLR smsc=%s, ts=%s, dst=%s, type=%d", dlr_type(), octstr_get_cstr(smsc), octstr_get_cstr(ts), octstr_get_cstr(dst), typ); - dlr = handles->dlr_get(smsc, ts, dst); - if (dlr == NULL) { - warning(0, "DLR[%s]: DLR from SMSC<%s> for DST<%s> not found.", - dlr_type(), octstr_get_cstr(smsc), octstr_get_cstr(dst)); - return NULL; + /* + * Retry the dlr search on the DB if not found at first attempt. + * This could happen specially with DB storage when using separate + * binds for sending and receiving. + */ + while(retry < handles->retry_count) { + if (retry++ > 0) { + debug("dlr.dlr", 0, "Sleeping for %1.3f seconds", handles->retry_delay); + gwthread_sleep(handles->retry_delay); + } + dlr = handles->dlr_get(smsc, ts, dst); + + if (dlr != NULL) + break; + + debug("dlr.dlr", 0, "DLR from SMSC<%s> for DST<%s>. Attempt %d of %d.", + octstr_get_cstr(smsc), octstr_get_cstr(dst), retry, handles->retry_count); } + if (dlr == NULL) { + warning(0, "DLR[%s]: DLR from SMSC<%s> for DST<%s> not found after %d attempts.", + dlr_type(), octstr_get_cstr(smsc), octstr_get_cstr(dst), handles->retry_count); + return NULL; + } #define O_SET(x, val) if (octstr_len(val) > 0) { x = val; val = NULL; } if ((typ & dlr->mask) > 0) { Index: gw/dlr_p.h =================================================================== --- gw/dlr_p.h (revision 27) +++ gw/dlr_p.h (working copy) @@ -137,6 +137,14 @@ * Shutdown storage */ void (*dlr_shutdown) (void); + /* + * How many times do we retry the dlr_find? + */ + long retry_count; + /* + * Delay between the retries + */ + double retry_delay; }; /*