Index: gw/dlr_mysql.c
===================================================================
--- gw/dlr_mysql.c	(revision 4833)
+++ gw/dlr_mysql.c	(working copy)
@@ -138,7 +138,7 @@
 
 static struct dlr_entry* dlr_mysql_get(const Octstr *smsc, const Octstr *ts, const Octstr *dst)
 {
-    Octstr *sql;
+    Octstr *sql, *like;
     DBPoolConn *pconn;
     List *result = NULL, *row;
     struct dlr_entry *res = NULL;
@@ -148,15 +148,22 @@
     if (pconn == NULL) /* should not happens, but sure is sure */
         return NULL;
 
-    sql = octstr_format("SELECT `%S`, `%S`, `%S`, `%S`, `%S`, `%S` FROM `%S` WHERE `%S`=? AND `%S`=? LIMIT 1",
+    if (dst)
+       like = octstr_format("AND `%S` LIKE CONCAT('%%', ?)", fields->field_dst);
+    else
+       like = octstr_imm("");
+
+       sql = octstr_format("SELECT `%S`, `%S`, `%S`, `%S`, `%S`, `%S` FROM `%S` WHERE `%S`=? AND `%S`=? %S LIMIT 1",
                         fields->field_mask, fields->field_serv,
                         fields->field_url, fields->field_src,
                         fields->field_dst, fields->field_boxc,
                         fields->table, fields->field_smsc,
-                        fields->field_ts);
+                        fields->field_ts, like);
 
     gwlist_append(binds, (Octstr *)smsc);
     gwlist_append(binds, (Octstr *)ts);
+    if (dst)
+       gwlist_append(binds, (Octstr *)dst);
 
 #if defined(DLR_TRACE)
     debug("dlr.mysql", 0, "sql: %s", octstr_get_cstr(sql));
@@ -164,10 +171,12 @@
 
     if (dbpool_conn_select(pconn, sql, binds, &result) != 0) {
         octstr_destroy(sql);
+        octstr_destroy(like);
         dbpool_conn_produce(pconn);
         return NULL;
     }
     octstr_destroy(sql);
+    octstr_destroy(like);
     gwlist_destroy(binds, NULL);
     dbpool_conn_produce(pconn);
 
@@ -195,7 +204,7 @@
 
 static void dlr_mysql_remove(const Octstr *smsc, const Octstr *ts, const Octstr *dst)
 {
-    Octstr *sql;
+    Octstr *sql, *like;
     DBPoolConn *pconn;
     List *binds = gwlist_create();
     int res;
@@ -207,12 +216,19 @@
     if (pconn == NULL)
         return;
 
-    sql = octstr_format("DELETE FROM `%S` WHERE `%S`=? AND `%S`=? LIMIT 1",
+    if (dst)
+       like = octstr_format("AND `%S` LIKE CONCAT('%%', ?)", fields->field_dst);
+    else
+       like = octstr_imm("");
+
+       sql = octstr_format("DELETE FROM `%S` WHERE `%S`=? AND `%S`=? %S LIMIT 1",
                         fields->table, fields->field_smsc,
-                        fields->field_ts);
+                        fields->field_ts, like);
 
     gwlist_append(binds, (Octstr *)smsc);
     gwlist_append(binds, (Octstr *)ts);
+    if (dst)
+       gwlist_append(binds, (Octstr *)dst);
 
 #if defined(DLR_TRACE)
     debug("dlr.mysql", 0, "sql: %s", octstr_get_cstr(sql));
@@ -226,11 +242,12 @@
     dbpool_conn_produce(pconn);
     gwlist_destroy(binds, NULL);
     octstr_destroy(sql);
+    octstr_destroy(like);
 }
 
 static void dlr_mysql_update(const Octstr *smsc, const Octstr *ts, const Octstr *dst, int status)
 {
-    Octstr *sql, *os_status;
+    Octstr *sql, *os_status, *like;
     DBPoolConn *pconn;
     List *binds = gwlist_create();
     int res;
@@ -242,14 +259,22 @@
     if (pconn == NULL)
         return;
 
-    sql = octstr_format("UPDATE `%S` SET `%S`=? WHERE `%S`=? AND `%S`=? LIMIT 1",
+    if (dst)
+       like = octstr_format("AND `%S` LIKE CONCAT('%%', ?)", fields->field_dst);
+    else
+       like = octstr_imm("");
+
+       sql = octstr_format("UPDATE `%S` SET `%S`=? WHERE `%S`=? AND `%S`=? %S LIMIT 1",
                         fields->table, fields->field_status,
-                        fields->field_smsc, fields->field_ts);
+                        fields->field_smsc, fields->field_ts,
+                        like);
 
     os_status = octstr_format("%d", status);
     gwlist_append(binds, (Octstr *)os_status);
     gwlist_append(binds, (Octstr *)smsc);
     gwlist_append(binds, (Octstr *)ts);
+    if (dst)
+       gwlist_append(binds, (Octstr *)like);
 
 #if defined(DLR_TRACE)
     debug("dlr.mysql", 0, "sql: %s", octstr_get_cstr(sql));
@@ -263,9 +288,9 @@
     gwlist_destroy(binds, NULL);
     octstr_destroy(os_status);
     octstr_destroy(sql);
+    octstr_destroy(like);
 }
 
-
 static long dlr_mysql_messages(void)
 {
     List *result, *row;
@@ -446,4 +471,3 @@
     return NULL;
 }
 #endif /* HAVE_MYSQL */
-
Index: gw/dlr_oracle.c
===================================================================
--- gw/dlr_oracle.c	(revision 4833)
+++ gw/dlr_oracle.c	(working copy)
@@ -171,7 +171,7 @@
 
 static void dlr_remove_oracle(const Octstr *smsc, const Octstr *ts, const Octstr *dst)
 {
-    Octstr *sql;
+    Octstr *sql, *like;
     DBPoolConn *pconn;
     List *binds = gwlist_create();
     int res;
@@ -183,13 +183,19 @@
     if (pconn == NULL)
         return;
 
-    sql = octstr_format("DELETE FROM %S WHERE %S=:1 AND %S=:2 AND %S=:3 AND ROWNUM < 2",
+    if (dst)
+       like = octstr_format("AND %S LIKE CONCAT('%%', :3)", fields->field_dst);
+    else
+       like = octstr_imm("");
+
+       sql = octstr_format("DELETE FROM %S WHERE %S=:1 AND %S=:2 %S AND ROWNUM < 2",
                         fields->table, fields->field_smsc,
-                        fields->field_ts, fields->field_dst);
+                        fields->field_ts, like);
 
     gwlist_append(binds, (Octstr *)smsc);      /* :1 */
     gwlist_append(binds, (Octstr *)ts);        /* :2 */
-    gwlist_append(binds, (Octstr *)dst);       /* :3 */
+    if (dst)                                            /* :3 */
+       gwlist_append(binds, (Octstr *)dst);
 
 #if defined(DLR_TRACE)
     debug("dlr.oracle", 0, "sql: %s", octstr_get_cstr(sql));
@@ -203,11 +209,12 @@
     dbpool_conn_produce(pconn);
     gwlist_destroy(binds, NULL);
     octstr_destroy(sql);
+    octstr_destroy(like);
 }
 
 static struct dlr_entry* dlr_get_oracle(const Octstr *smsc, const Octstr *ts, const Octstr *dst)
 {
-    Octstr *sql;
+    Octstr *sql, *like;
     DBPoolConn *pconn;
     List *result = NULL, *row;
     struct dlr_entry *res = NULL;
@@ -217,26 +224,35 @@
     if (pconn == NULL) /* should not happens, but sure is sure */
         return NULL;
 
-    sql = octstr_format("SELECT %S, %S, %S, %S, %S, %S FROM %S WHERE %S=:1 AND %S=:2 AND %S=:3 AND ROWNUM < 2",
+    if (dst)
+       like = octstr_format("AND %S LIKE CONCAT('%%', :3)",
+              fields->field_dst);
+    else
+       like = octstr_imm("");
+
+       sql = octstr_format("SELECT %S, %S, %S, %S, %S, %S FROM %S WHERE %S=:1 AND %S=:2 %S ROWNUM < 2",
                         fields->field_mask, fields->field_serv,
                         fields->field_url, fields->field_src,
                         fields->field_dst, fields->field_boxc,
                         fields->table, fields->field_smsc,
-                        fields->field_ts, fields->field_dst);
+                        fields->field_ts, like);
 
     gwlist_append(binds, (Octstr *)smsc);      /* :1 */
     gwlist_append(binds, (Octstr *)ts);        /* :2 */
-    gwlist_append(binds, (Octstr *)dst);       /* :3 */
+    if (dst)                                            /* :3 */
+       gwlist_append(binds, (Octstr *)dst);
 
 #if defined(DLR_TRACE)
     debug("dlr.oracle", 0, "sql: %s", octstr_get_cstr(sql));
 #endif
     if (dbpool_conn_select(pconn, sql, binds, &result) != 0) {
         octstr_destroy(sql);
+        octstr_destroy(like);
         dbpool_conn_produce(pconn);
         return NULL;
     }
     octstr_destroy(sql);
+    octstr_destroy(like);
     gwlist_destroy(binds, NULL);
     dbpool_conn_produce(pconn);
 
@@ -264,7 +280,7 @@
 
 static void dlr_update_oracle(const Octstr *smsc, const Octstr *ts, const Octstr *dst, int status)
 {
-    Octstr *sql, *os_status;
+    Octstr *sql, *os_status, *like;
     DBPoolConn *pconn;
     List *binds = gwlist_create();
     int res;
@@ -276,15 +292,22 @@
     if (pconn == NULL)
         return;
 
-    sql = octstr_format("UPDATE %S SET %S=:1 WHERE %S=:2 AND %S=:3 AND %S=:4 AND ROWNUM < 2",
+    if (dst)
+       like = octstr_format("AND %S LIKE CONCAT('%%', :4)", fields->field_dst);
+    else
+       like = octstr_imm("");
+
+       sql = octstr_format("UPDATE %S SET %S=:1 WHERE %S=:2 AND %S=:3 %S AND ROWNUM < 2",
                         fields->table, fields->field_status,
-                        fields->field_smsc, fields->field_ts, fields->field_dst);
+                        fields->field_smsc, fields->field_ts, like);
 
     os_status = octstr_format("%d", status);
     gwlist_append(binds, (Octstr *)os_status); /* :1 */
     gwlist_append(binds, (Octstr *)smsc);      /* :2 */
     gwlist_append(binds, (Octstr *)ts);        /* :3 */
-    gwlist_append(binds, (Octstr *)dst);       /* :4 */
+    if (dst)                                            /* :4 */
+       gwlist_append(binds, (Octstr *)dst);
+
 #if defined(DLR_TRACE)
     debug("dlr.oracle", 0, "sql: %s", octstr_get_cstr(sql));
 #endif
@@ -297,6 +320,7 @@
     gwlist_destroy(binds, NULL);
     octstr_destroy(os_status);
     octstr_destroy(sql);
+    octstr_destroy(like);
 }
 
 static void dlr_flush_oracle (void)
Index: gw/dlr_pgsql.c
===================================================================
--- gw/dlr_pgsql.c	(revision 4833)
+++ gw/dlr_pgsql.c	(working copy)
@@ -165,19 +165,23 @@
 static struct dlr_entry *dlr_pgsql_get(const Octstr *smsc, const Octstr *ts, const Octstr *dst)
 {
     struct dlr_entry *res = NULL;
-    Octstr *sql;
+    Octstr *sql, *like;
     List *result, *row;
 
-    sql = octstr_format("SELECT \"%s\", \"%s\", \"%s\", \"%s\", \"%s\", \"%s\" FROM \"%s\" WHERE \"%s\"='%s' AND \"%s\"='%s' LIMIT 1;",
-                        octstr_get_cstr(fields->field_mask), octstr_get_cstr(fields->field_serv),
-                        octstr_get_cstr(fields->field_url), octstr_get_cstr(fields->field_src),
-                        octstr_get_cstr(fields->field_dst), octstr_get_cstr(fields->field_boxc),
-                        octstr_get_cstr(fields->table), octstr_get_cstr(fields->field_smsc),
-                        octstr_get_cstr(smsc), octstr_get_cstr(fields->field_ts), octstr_get_cstr(ts));
+    if (dst)
+       like = octstr_format("AND \"%S\" LIKE '%%%S'", fields->field_dst, dst);
+    else
+       like = octstr_imm("");
 
+    sql = octstr_format("SELECT \"%S\", \"%S\", \"%S\", \"%S\", \"%S\", "
+          "\"%S\" FROM \"%S\" WHERE \"%S\"='%S' AND \"%S\"='%S' %S LIMIT 1;",
+          fields->field_mask, fields->field_serv, fields->field_url,
+          fields->field_src, fields->field_dst, fields->field_boxc,
+          fields->table, fields->field_smsc, smsc, fields->field_ts, ts, like);
 
     result = pgsql_select(sql);
     octstr_destroy(sql);
+    octstr_destroy(like);
 
     if (result == NULL || gwlist_len(result) < 1) {
         debug("dlr.pgsql", 0, "no rows found");
@@ -186,7 +190,7 @@
         gwlist_destroy(result, NULL);
         return NULL;
     }
-    
+
     row = gwlist_get(result, 0);
 
     debug("dlr.pgsql", 0, "Found entry, col1=%s, col2=%s, col3=%s, col4=%s, col5=%s col6=%s",
@@ -211,42 +215,52 @@
     while((row = gwlist_extract_first(result)))
         gwlist_destroy(row, octstr_destroy_item);
     gwlist_destroy(result, NULL);
-    
+
     return res;
 }
 
 
 static void dlr_pgsql_remove(const Octstr *smsc, const Octstr *ts, const Octstr *dst)
 {
-    Octstr *sql;
+    Octstr *sql, *like;
 
     debug("dlr.pgsql", 0, "removing DLR from database");
-    sql = octstr_format("DELETE FROM \"%s\" WHERE oid = (SELECT oid FROM \"%s\" WHERE \"%s\"='%s' AND \"%s\"='%s' LIMIT 1);",
-                        octstr_get_cstr(fields->table), octstr_get_cstr(fields->table),
-                        octstr_get_cstr(fields->field_smsc),
-                        octstr_get_cstr(smsc), octstr_get_cstr(fields->field_ts), octstr_get_cstr(ts));
+    if (dst)
+       like = octstr_format("AND \"%S\" LIKE '%%%S'", fields->field_dst, dst);
+    else
+       like = octstr_imm("");
 
+    sql = octstr_format("DELETE FROM \"%S\" WHERE oid = (SELECT oid FROM "
+          "\"%S\" WHERE \"%S\"='%S' AND \"%S\"='%S' %S LIMIT 1);",
+          fields->table, fields->table, fields->field_smsc, smsc,
+          fields->field_ts, ts, like);
 
     if (!pgsql_update(sql))
        warning(0, "DLR: PGSQL: No dlr deleted for DST<%s>", octstr_get_cstr(dst));
     octstr_destroy(sql);
+    octstr_destroy(like);
 }
 
 
 static void dlr_pgsql_update(const Octstr *smsc, const Octstr *ts, const Octstr *dst, int status)
 {
-    Octstr *sql;
+    Octstr *sql, *like;
 
     debug("dlr.pgsql", 0, "updating DLR status in database");
-    sql = octstr_format("UPDATE \"%s\" SET \"%s\"=%d WHERE oid = (SELECT oid FROM \"%s\" WHERE \"%s\"='%s' AND \"%s\"='%s' LIMIT 1);",
-                        octstr_get_cstr(fields->table),
-                        octstr_get_cstr(fields->field_status), status,
-                        octstr_get_cstr(fields->table),
-                        octstr_get_cstr(fields->field_smsc), octstr_get_cstr(smsc),
-                        octstr_get_cstr(fields->field_ts), octstr_get_cstr(ts));
+    if (dst)
+       like = octstr_format("AND \"%S\" LIKE '%%%S'", fields->field_dst, dst);
+    else
+       like = octstr_imm("");
+
+    sql = octstr_format("UPDATE \"%S\" SET \"%S\"=%d WHERE oid = (SELECT "
+        "oid FROM \"%S\" WHERE \"%S\"='%S' AND \"%S\"='%S' %S LIMIT 1);",
+        fields->table, fields->field_status, status, fields->table,
+        fields->field_smsc, smsc, fields->field_ts, ts, like);
+
     if (!pgsql_update(sql))
        warning(0, "DLR: PGSQL: No dlr updated for DST<%s> (status: %d)", octstr_get_cstr(dst), status);
     octstr_destroy(sql);
+    octstr_destroy(like);
 }
 
 
Index: gw/dlr_mem.c
===================================================================
--- gw/dlr_mem.c	(revision 4833)
+++ gw/dlr_mem.c	(working copy)
@@ -125,8 +125,28 @@
     /* XXX: check destination addr too, because e.g. for UCP is not enough to check only
      *          smsc and timestamp (timestamp is even without milliseconds)
      */
-    if(octstr_compare(dlr->smsc,smsc) == 0 && octstr_compare(dlr->timestamp,ts) == 0)
+    if (dst){
+       Octstr *dst_min;
+       int len1 = octstr_len(dlr->destination), len2 = octstr_len(dst);
+
+       if (len1 < len2)
+          return(1);
+
+       dst_min = octstr_duplicate(dlr->destination);
+       if (len1 > len2)
+             octstr_delete(dst_min, 0, len1 - len2);
+
+       if (octstr_compare(dlr->smsc, smsc) == 0 && octstr_compare(dlr->
+           timestamp, ts) == 0 && octstr_compare(dst_min, dst) == 0) {
+           octstr_destroy(dst_min);
         return 0;
+       }
+       octstr_destroy(dst_min);
+    }
+    else
+       if (octstr_compare(dlr->smsc, smsc) == 0 && octstr_compare(dlr->
+           timestamp, ts) == 0)
+           return 0;
 
     return 1;
 }
Index: gw/dlr_mssql.c
===================================================================
--- gw/dlr_mssql.c	(revision 4833)
+++ gw/dlr_mssql.c	(working copy)
@@ -161,7 +161,7 @@
 
 static void dlr_remove_mssql(const Octstr *smsc, const Octstr *ts, const Octstr *dst)
 {
-    Octstr *sql;
+    Octstr *sql, *like;
     DBPoolConn *pconn;
     int res;
 
@@ -172,12 +172,15 @@
     if (pconn == NULL)
         return;
 
-    sql = octstr_format("SET ROWCOUNT 1\n"
-            "DELETE FROM %S WHERE %S='%S' AND %S='%S'\n"
-            "SET ROWCOUNT 0",
-            fields->table, fields->field_smsc, smsc,
-            fields->field_ts, ts);
+    if (dst)
+       like = octstr_format("AND %S LIKE '%%%S'", fields->field_dst, dst);
+    else
+       like = octstr_imm("");
 
+    sql = octstr_format("SET ROWCOUNT 1\nDELETE FROM %S WHERE %S='%S' AND "
+         "%S='%S' %S \nSET ROWCOUNT 0", fields->table, fields->field_smsc,
+         smsc, fields->field_ts, ts, like);
+
 #if defined(DLR_TRACE)
     debug("dlr.mssql", 0, "sql: %s", octstr_get_cstr(sql));
 #endif
@@ -189,11 +192,12 @@
 
     dbpool_conn_produce(pconn);
     octstr_destroy(sql);
+    octstr_destroy(like);
 }
 
 static struct dlr_entry* dlr_get_mssql(const Octstr *smsc, const Octstr *ts, const Octstr *dst)
 {
-    Octstr *sql;
+    Octstr *sql, *like;
     DBPoolConn *pconn;
     List *result = NULL, *row;
     struct dlr_entry *res = NULL;
@@ -202,11 +206,17 @@
     if (pconn == NULL) /* should not happens, but sure is sure */
         return NULL;
 
-    sql = octstr_format("SELECT %S, %S, %S, %S, %S, %S FROM %S WHERE %S='%S' AND %S='%S'",
-                fields->field_mask, fields->field_serv, fields->field_url,
-                fields->field_src, fields->field_dst, fields->field_boxc,
-                fields->table, fields->field_smsc, smsc, fields->field_ts, ts);
+    if (dst)
+       like = octstr_format("AND %S LIKE '%%%S'", fields->field_dst, dst);
+    else
+       like = octstr_imm("");
 
+    sql = octstr_format("SELECT %S, %S, %S, %S, %S, %S FROM %S WHERE %S='%S'"
+          " AND %S='%S' %S", fields->field_mask, fields->field_serv,
+          fields->field_url, fields->field_src, fields->field_dst,
+          fields->field_boxc, fields->table, fields->field_smsc, smsc,
+          fields->field_ts, ts, like);
+
 #if defined(DLR_TRACE)
     debug("dlr.mssql", 0, "sql: %s", octstr_get_cstr(sql));
 #endif
@@ -216,6 +226,7 @@
         return NULL;
     }
     octstr_destroy(sql);
+    octstr_destroy(like);
     dbpool_conn_produce(pconn);
 
 #define LO2CSTR(r, i) octstr_get_cstr(gwlist_get(r, i))
@@ -242,7 +253,7 @@
 
 static void dlr_update_mssql(const Octstr *smsc, const Octstr *ts, const Octstr *dst, int status)
 {
-    Octstr *sql, *os_status;
+    Octstr *sql, *like;
     DBPoolConn *pconn;
     int res;
 
@@ -253,12 +264,16 @@
     if (pconn == NULL)
         return;
 
-    sql = octstr_format("SET ROWCOUNT 1\n"
-            "UPDATE %S SET %S=%d WHERE %S='%S' AND %S='%S'\n"
-            "SET ROWCOUNT 0",
-            fields->table, fields->field_status, status,
-            fields->field_smsc, smsc, fields->field_ts, ts);
+    if (dst)
+       like = octstr_format("AND %S LIKE '%%%S'", fields->field_dst, dst);
+    else
+       like = octstr_imm("");
 
+    sql = octstr_format("SET ROWCOUNT 1\nUPDATE %S SET %S=%d WHERE %S='%S' "
+        "AND %S='%S' %S\nSET ROWCOUNT 0",
+        fields->table, fields->field_status, status, fields->field_smsc, smsc,
+        fields->field_ts, ts, like);
+
 #if defined(DLR_TRACE)
     debug("dlr.mssql", 0, "sql: %s", octstr_get_cstr(sql));
 #endif
@@ -268,8 +283,8 @@
         warning(0, "DLR: MSSQL: No dlr found to update for DST<%s> (status: %d)", octstr_get_cstr(dst), status);
 
     dbpool_conn_produce(pconn);
-    octstr_destroy(os_status);
     octstr_destroy(sql);
+    octstr_destroy(like);
 }
 
 static void dlr_flush_mssql (void)
Index: gw/dlr_sdb.c
===================================================================
--- gw/dlr_sdb.c	(revision 4833)
+++ gw/dlr_sdb.c	(working copy)
@@ -212,26 +212,31 @@
 
 static struct dlr_entry*  dlr_sdb_get(const Octstr *smsc, const Octstr *ts, const Octstr *dst)
 {
-    Octstr *sql;
+    Octstr *sql, *like;
     int	state;
     struct dlr_entry *res = dlr_entry_create();
 
     gw_assert(res != NULL);
 
-    sql = octstr_format("SELECT %s, %s, %s, %s, %s, %s FROM %s WHERE %s='%s' AND %s='%s' %s",
-                        octstr_get_cstr(fields->field_mask), octstr_get_cstr(fields->field_serv),
-                        octstr_get_cstr(fields->field_url), octstr_get_cstr(fields->field_src),
-                        octstr_get_cstr(fields->field_dst), octstr_get_cstr(fields->field_boxc),
-                        octstr_get_cstr(fields->table),
-                        octstr_get_cstr(fields->field_smsc), octstr_get_cstr(smsc),
-                        octstr_get_cstr(fields->field_ts), octstr_get_cstr(ts), sdb_get_limit_str());
+    if (dst)
+       like = octstr_format("AND \"%S\" LIKE '%%%S' %s", fields->field_dst,
+              dst, sdb_get_limit_str());
+    else
+       like = octstr_imm(sdb_get_limit_str());
 
+    sql = octstr_format("SELECT %S, %S, %S, %S, %S, %S FROM %S WHERE %S='%S' "
+          "AND %S='%S' %S", fields->field_mask, fields->field_serv,
+          fields->field_url, fields->field_src, fields->field_dst,
+          fields->field_boxc, fields->table, fields->field_smsc, smsc,
+          fields->field_ts, ts, like);
+
 #if defined(DLR_TRACE)
      debug("dlr.sdb", 0, "SDB: sql: %s", octstr_get_cstr(sql));
 #endif
 
     state = gw_sdb_query(octstr_get_cstr(sql), sdb_callback_add, res);
     octstr_destroy(sql);
+    octstr_destroy(like);
     if (state == -1) {
         error(0, "SDB: error in finding DLR");
         goto notfound;
@@ -252,22 +257,28 @@
 
 static void  dlr_sdb_update(const Octstr *smsc, const Octstr *ts, const Octstr *dst, int status)
 {
-    Octstr *sql;
+    Octstr *sql, *like;
     int	state;
 
     debug("dlr.sdb", 0, "SDB: updating DLR status in database");
-    sql = octstr_format("UPDATE %s SET %s=%d WHERE %s='%s' AND %s='%s' %s",
-                        octstr_get_cstr(fields->table),
-                        octstr_get_cstr(fields->field_status), status,
-                        octstr_get_cstr(fields->field_smsc), octstr_get_cstr(smsc),
-                        octstr_get_cstr(fields->field_ts), octstr_get_cstr(ts), sdb_get_limit_str());
 
+    if (dst)
+       like = octstr_format("AND \"%S\" LIKE '%%%S' %s", fields->field_dst,
+              dst, sdb_get_limit_str());
+    else
+       like = octstr_imm(sdb_get_limit_str());
+
+    sql = octstr_format("UPDATE %S SET %S=%d WHERE %S='%S' AND %S='%S' %S",
+          fields->table, fields->field_status, status, fields->field_smsc,
+          smsc, fields->field_ts, ts, like);
+
 #if defined(DLR_TRACE)
      debug("dlr.sdb", 0, "SDB: sql: %s", octstr_get_cstr(sql));
 #endif
 
     state = gw_sdb_query(octstr_get_cstr(sql), NULL, NULL);
     octstr_destroy(sql);
+    octstr_destroy(like);
     if (state == -1)
         error(0, "SDB: error in updating DLR");
     else if (!state)
@@ -276,7 +287,7 @@
 
 static void  dlr_sdb_remove(const Octstr *smsc, const Octstr *ts, const Octstr *dst)
 {
-    Octstr *sql;
+    Octstr *sql, *like;
     int	state;
 
     debug("dlr.sdb", 0, "removing DLR from database");
@@ -288,17 +299,24 @@
          * to do vacuum regularly, even if it's virtually impossible
          * to hit duplicates since oid's are given in a row
          */
-        sql = octstr_format("DELETE FROM %s WHERE oid = \
-                            (SELECT oid FROM %s WHERE %s='%s' AND %s='%s' LIMIT 1)",
-                            octstr_get_cstr(fields->table),
-                            octstr_get_cstr(fields->table),
-                            octstr_get_cstr(fields->field_smsc), octstr_get_cstr(smsc),
-                            octstr_get_cstr(fields->field_ts), octstr_get_cstr(ts));
+       if (dst)
+          like = octstr_format("AND \"%S\" LIKE '%%%S' LIMIT 1)",
+                fields->field_dst, dst);
+       else
+          like = octstr_imm("LIMIT 1)");
+       sql = octstr_format("DELETE FROM %S WHERE oid = (SELECT oid FROM %S "
+             "WHERE %S='%S' AND %S='%S' %S", fields->table, fields->table,
+             fields->field_smsc, smsc, fields->field_ts, ts, like);
     } else {
-        sql = octstr_format("DELETE FROM %s WHERE %s='%s' AND %s='%s' %s",
-                            octstr_get_cstr(fields->table),
-                            octstr_get_cstr(fields->field_smsc), octstr_get_cstr(smsc),
-                            octstr_get_cstr(fields->field_ts), octstr_get_cstr(ts), sdb_get_limit_str());
+       if (dst)
+          like = octstr_format("AND \"%S\" LIKE '%%%S' %s", fields->field_dst,
+                 dst, sdb_get_limit_str());
+       else
+          like = octstr_imm(sdb_get_limit_str());
+
+       sql = octstr_format("DELETE FROM %S WHERE %S='%S' AND %S='%S' %S",
+             fields->table, fields->field_smsc, smsc, fields->field_ts, ts,
+             like);
     }
 
 #if defined(DLR_TRACE)
@@ -307,6 +325,7 @@
 
     state = gw_sdb_query(octstr_get_cstr(sql), NULL, NULL);
     octstr_destroy(sql);
+    octstr_destroy(like);
     if (state == -1)
         error(0, "SDB: error in deleting DLR");
     else if (!state)
Index: gw/dlr.c
===================================================================
--- gw/dlr.c	(revision 4833)
+++ gw/dlr.c	(working copy)
@@ -371,10 +371,11 @@
  * NOTE: If typ is end status (e.g. DELIVERED) then dlr entry
  *       will be removed from DB.
  */
-Msg *dlr_find(const Octstr *smsc, const Octstr *ts, const Octstr *dst, int typ)
+Msg *dlr_find(const Octstr *smsc, const Octstr *ts, const Octstr *dst, int typ, int use_dst)
 {
     Msg	*msg = NULL;
     struct dlr_entry *dlr = NULL;
+	 Octstr *dst_min = NULL;
     
     if(octstr_len(smsc) == 0) {
 	warning(0, "DLR[%s]: Can't find a dlr without smsc-id", dlr_type());
@@ -385,10 +386,17 @@
     if (handles == NULL || handles->dlr_get == NULL)
         return NULL;
 
+    if (use_dst && dst) {
+       dst_min = octstr_duplicate(dst);
+       int len = octstr_len(dst);
+
+       if (len > MIN_DST_LEN)
+          octstr_delete(dst_min, 0, len - MIN_DST_LEN);
+	 }
     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);
+    dlr = handles->dlr_get(smsc, ts, dst_min);
     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));         
@@ -436,12 +444,13 @@
     if ((typ & DLR_BUFFERED) && ((dlr->mask & DLR_SUCCESS) || (dlr->mask & DLR_FAIL))) {
         debug("dlr.dlr", 0, "DLR[%s]: DLR not destroyed, still waiting for other delivery report", dlr_type());
         /* update dlr entry status if function defined */
-        if (handles != NULL && handles->dlr_update != NULL)
-            handles->dlr_update(smsc, ts, dst, typ);
+        if (handles != NULL && handles->dlr_update != NULL){
+            handles->dlr_update(smsc, ts, dst_min, typ);
+        }
     } else {
-        if (handles != NULL && handles->dlr_remove != NULL) {
+        if (handles != NULL && handles->dlr_remove != NULL){
             /* it's not good for internal storage, but better for all others */
-            handles->dlr_remove(smsc, ts, dst);
+            handles->dlr_remove(smsc, ts, dst_min);
         } else {
             warning(0, "DLR[%s]: Storage don't have remove operation defined", dlr_type());
         }
@@ -449,6 +458,7 @@
 
     /* destroy struct dlr_entry */
     dlr_entry_destroy(dlr);
+   octstr_destroy(dst_min);
 
     return msg;
 }
Index: gw/dlr.h
===================================================================
--- gw/dlr.h	(revision 4833)
+++ gw/dlr.h	(working copy)
@@ -103,7 +103,8 @@
  * Find an entry in the list. If there is one a message is returned and 
  * the entry is removed from the list otherwhise the message returned is NULL 
  */
-Msg* dlr_find(const Octstr *smsc, const Octstr *ts, const Octstr *dst, int type);
+Msg* dlr_find(const Octstr *smsc, const Octstr *ts, const Octstr *dst, int type,
+ int use_dst);
 
 /* return the number of DLR messages in the current waiting queue */
 long dlr_messages(void);
Index: gw/dlr_p.h
===================================================================
--- gw/dlr_p.h	(revision 4833)
+++ gw/dlr_p.h	(working copy)
@@ -70,6 +70,8 @@
 
 #define DLR_TRACE 1
 
+/* Used in destination based queries for EMI/UUCP DLRs */
+#define MIN_DST_LEN 7
 /*
  * The structure of a delivery report  entry.
  */
Index: gw/smsc/smsc_cimd2.c
===================================================================
--- gw/smsc/smsc_cimd2.c	(revision 4833)
+++ gw/smsc/smsc_cimd2.c	(working copy)
@@ -2114,7 +2114,7 @@
         code = 0;
     }
     if(code)
-    	msg = dlr_find(conn->name, timestamp, destination, code);
+    	msg = dlr_find(conn->name, timestamp, destination, code, 1);
     else
         msg = NULL;
 
Index: gw/smsc/smsc_soap.c
===================================================================
--- gw/smsc/smsc_soap.c	(revision 4833)
+++ gw/smsc/smsc_soap.c	(working copy)
@@ -1616,7 +1616,7 @@
     /* fetch the DLR */
 
     dlrmsg = dlr_find(conn->id, octstr_imm(msgid), octstr_imm("receiver"), /* destination */
-                      dlrtype);
+                      dlrtype, 0);
 
     if (!dlrmsg) {
         error(0,"SOAP[%s]: parse_dlr invoked (%ld), but no DLR found for MsgID %s", octstr_get_cstr(privdata->name),dlrtype,msgid);
Index: gw/smsc/smsc_oisd.c
===================================================================
--- gw/smsc/smsc_oisd.c	(revision 4833)
+++ gw/smsc/smsc_oisd.c	(working copy)
@@ -1306,7 +1306,7 @@
     }
 
     if (code)
-        msg = dlr_find(conn->name, timestamp, destination, code);
+        msg = dlr_find(conn->name, timestamp, destination, code, 0);
 
     octstr_destroy(destination);
     octstr_destroy(timestamp);
Index: gw/smsc/smsc_at.c
===================================================================
--- gw/smsc/smsc_at.c	(revision 4833)
+++ gw/smsc/smsc_at.c	(working copy)
@@ -2124,7 +2124,7 @@
      * categories. It will catch "reserved" values where the first 3 MSBits 
      * are not set as "Success" which may not be correct. */
 
-    if ((dlrmsg = dlr_find(privdata->conn->id, msg_id, receiver, type)) == NULL) {
+    if ((dlrmsg = dlr_find(privdata->conn->id, msg_id, receiver, type, 0)) == NULL) {
         debug("bb.smsc.at2", 1, "AT2[%s]: Received delivery notification but can't find that ID in the DLR storage",
               octstr_get_cstr(privdata->name));
 	    goto error;
Index: gw/smsc/smsc_fake.c
===================================================================
--- gw/smsc/smsc_fake.c	(revision 4833)
+++ gw/smsc/smsc_fake.c	(working copy)
@@ -291,7 +291,7 @@
                     dlrmsg = dlr_find(conn->id,
                                       tmp, /* smsc message id */
                                       copy->sms.receiver, /* destination */
-                                      dlrstat);
+                                      dlrstat, 0);
                     if (dlrmsg != NULL) {
                         /* XXX TODO: Provide a SMPP DLR text in msgdata */
                         bb_smscconn_receive(conn, dlrmsg);
Index: gw/smsc/smsc_http.c
===================================================================
--- gw/smsc/smsc_http.c	(revision 4833)
+++ gw/smsc/smsc_http.c	(working copy)
@@ -643,7 +643,7 @@
         dlrmsg = dlr_find(conn->id,
             dlrmid, /* message id */
             to, /* destination */
-            dlrmask);
+            dlrmask, 0);
 
         if (dlrmsg != NULL) {
             dlrmsg->sms.sms_type = report_mo;
@@ -931,8 +931,8 @@
 	}
         dlrmsg = dlr_find(conn->id,
             apimsgid, /* smsc message id */
-            dest , /* destination */
-            dlrstat);
+            dest, /* destination */
+            dlrstat, 0);
 
         if (dlrmsg != NULL) {
             /* dlrmsg->sms.msgdata = octstr_duplicate(apimsgid); */
@@ -1410,8 +1410,8 @@
 
         dlrmsg = dlr_find(conn->id,
             mid, /* smsc message id */
-            dest , /* destination */
-            dlrstat);
+            dest, /* destination */
+            dlrstat, 0);
 
         if (dlrmsg != NULL) {
             dlrmsg->sms.msgdata = octstr_duplicate(mid);
@@ -1681,7 +1681,7 @@
         dlrmsg = dlr_find(conn->id,
             dlrmid, /* message id */
             to, /* destination */
-            dlrmask);
+            dlrmask, 0);
 
         if (dlrmsg != NULL) {
             dlrmsg->sms.sms_type = report_mo;
Index: gw/smsc/smsc_smpp.c
===================================================================
--- gw/smsc/smsc_smpp.c	(revision 4833)
+++ gw/smsc/smsc_smpp.c	(working copy)
@@ -1392,7 +1392,7 @@
         dlrmsg = dlr_find(smpp->conn->id,
             tmp, /* smsc message id */
             destination_addr, /* destination */
-            dlrstat);
+            dlrstat, 0);
 
         octstr_destroy(msgid);
     } else
Index: gw/smsc/smsc_cgw.c
===================================================================
--- gw/smsc/smsc_cgw.c	(revision 4833)
+++ gw/smsc/smsc_cgw.c	(working copy)
@@ -1137,19 +1137,19 @@
                 dlrmsg = dlr_find(conn->id,
                                             ts,     /* timestamp */
                                             msid,   /* destination */
-                                  DLR_SUCCESS);
+                                  DLR_SUCCESS, 0);
                 break;
             case 1:     /* buffered */
                 dlrmsg = dlr_find(conn->id,
                                             ts,     /* timestamp */
                                             msid,   /* destination */
-                                  DLR_BUFFERED);
+                                  DLR_BUFFERED, 0);
                 break;
             case 2:     /* not delivered */
                 dlrmsg = dlr_find(conn->id,
                                             ts,     /* timestamp */
                                             msid,   /* destination */
-                                  DLR_FAIL);
+                                  DLR_FAIL, 0);
                 break;
             }
 
