mirror of
https://github.com/servalproject/serval-dna.git
synced 2025-02-21 01:42:18 +00:00
Fix SEGV bug in new transaction cache code
This commit is contained in:
parent
8df5af7a93
commit
ceefd9b22b
53
server.c
53
server.c
@ -252,43 +252,40 @@ int processRequest(unsigned char *packet,int len,
|
||||
case ACTION_DIGITALTELEGRAM:
|
||||
if (debug&DEBUG_DNAREQUESTS) fprintf(stderr,"In ACTION_DIGITALTELEGRAM\n");
|
||||
{
|
||||
// Check transaction cache, to see if message has already been delivered. If not, then process it.
|
||||
int delivered = isTransactionInCache(transaction_id);
|
||||
if (!delivered) {
|
||||
// Unpack SMS message.
|
||||
char emitterPhoneNumber[256];
|
||||
char message[256];
|
||||
pofs++;
|
||||
/* char messageType = packet[pofs]; */
|
||||
pofs++;
|
||||
char emitterPhoneNumberLen = packet[pofs];
|
||||
pofs++;
|
||||
char messageLen = packet[pofs];
|
||||
pofs++;
|
||||
strncpy(emitterPhoneNumber, (const char*)packet+pofs, emitterPhoneNumberLen);
|
||||
emitterPhoneNumber[(unsigned int)emitterPhoneNumberLen]=0;
|
||||
|
||||
pofs+=emitterPhoneNumberLen;
|
||||
strncpy(message, (const char*)packet+pofs, messageLen);
|
||||
message[(unsigned int)messageLen]=0;
|
||||
|
||||
pofs+=messageLen;
|
||||
// Unpack SMS message.
|
||||
char emitterPhoneNumber[256];
|
||||
char message[256];
|
||||
pofs++;
|
||||
/* char messageType = packet[pofs]; */
|
||||
pofs++;
|
||||
char emitterPhoneNumberLen = packet[pofs];
|
||||
pofs++;
|
||||
char messageLen = packet[pofs];
|
||||
pofs++;
|
||||
strncpy(emitterPhoneNumber, (const char*)packet+pofs, emitterPhoneNumberLen);
|
||||
emitterPhoneNumber[(unsigned int)emitterPhoneNumberLen]=0;
|
||||
|
||||
// Check if I'm the recipient
|
||||
ofs=0;
|
||||
if (findHlr(hlr, &ofs, sid, did)){
|
||||
pofs+=emitterPhoneNumberLen;
|
||||
strncpy(message, (const char*)packet+pofs, messageLen);
|
||||
message[(unsigned int)messageLen]=0;
|
||||
|
||||
pofs+=messageLen;
|
||||
|
||||
// Check if I'm the recipient
|
||||
ofs=0;
|
||||
if (findHlr(hlr, &ofs, sid, did)) {
|
||||
// Check transaction cache to see if message has already been delivered. If not,
|
||||
// then deliver it now.
|
||||
if (!isTransactionInCache(transaction_id)) {
|
||||
// Deliver SMS to android.
|
||||
char amCommand[576]; // 64 char + 2*256(max) char = 576
|
||||
sprintf(amCommand, "am broadcast -a org.servalproject.DT -e number \"%s\" -e content \"%s\"", emitterPhoneNumber, message);
|
||||
if (debug&DEBUG_DNAREQUESTS) fprintf(stderr,"Delivering DT message via intent: %s\n",amCommand);
|
||||
runCommand(amCommand);
|
||||
delivered = 1;
|
||||
// Record in cache to prevent re-delivering the same message if a duplicate is received.
|
||||
insertTransactionInCache(transaction_id);
|
||||
}
|
||||
}
|
||||
if (delivered) {
|
||||
respondSimple(hlrSid(hlr, ofs), ACTION_OKAY, NULL, 0, transaction_id, recvttl,sender, CRYPT_CIPHERED|CRYPT_SIGNED);
|
||||
respondSimple(hlrSid(hlr, ofs), ACTION_OKAY, NULL, 0, transaction_id, recvttl, sender, CRYPT_CIPHERED|CRYPT_SIGNED);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -29,29 +29,37 @@ struct entry {
|
||||
struct entry *lru_next;
|
||||
};
|
||||
|
||||
static struct entry *buckets[TRANS_CACHE_SIZE];
|
||||
static int initialised = 0;
|
||||
static struct entry *buckets[TRANS_CACHE_BUCKETS];
|
||||
static struct entry *lru_head = NULL;
|
||||
static struct entry *lru_tail = NULL;
|
||||
// Static allocation of cache entry pool, but could easily be malloc'd
|
||||
// instead, in init_pool().
|
||||
// instead, in init_trans_cache().
|
||||
static struct entry entry_pool[TRANS_CACHE_SIZE];
|
||||
static struct entry *entry_freelist = NULL;
|
||||
static int entry_pool_initialised = 0;
|
||||
static int local_debug = 0;
|
||||
|
||||
/* Initialise the transaction cache entry pool.
|
||||
*
|
||||
* @author Andrew Bettison <andrew@servalproject.com>
|
||||
*/
|
||||
static void init_pool()
|
||||
static void init_trans_cache()
|
||||
{
|
||||
if (!entry_pool_initialised) {
|
||||
entry_freelist = NULL;
|
||||
if (!initialised) {
|
||||
if (local_debug) fprintf(stderr, "init_trans_cache() start\n");
|
||||
int i;
|
||||
for (i = 0; i != TRANS_CACHE_SIZE - 1; ++i) {
|
||||
entry_pool[i].bucket_next = entry_freelist;
|
||||
entry_freelist = &entry_pool[i];
|
||||
for (i = 0; i != TRANS_CACHE_BUCKETS; ++i) {
|
||||
buckets[i] = NULL;
|
||||
}
|
||||
entry_pool_initialised = 1;
|
||||
lru_head = lru_tail = entry_freelist = NULL;
|
||||
for (i = 0; i != TRANS_CACHE_SIZE; ++i) {
|
||||
struct entry *e = &entry_pool[i];
|
||||
e->bucket_next = entry_freelist;
|
||||
e->lru_prev = e->lru_next = NULL;
|
||||
entry_freelist = e;
|
||||
}
|
||||
initialised = 1;
|
||||
if (local_debug) fprintf(stderr, "init_trans_cache() done\n");
|
||||
}
|
||||
}
|
||||
|
||||
@ -82,10 +90,14 @@ static size_t hashTransactionId(unsigned char *transaction_id, size_t len)
|
||||
static struct entry * findTransactionCacheEntry(unsigned char *transaction_id)
|
||||
{
|
||||
size_t hash = hashTransactionId(transaction_id, TRANS_CACHE_BUCKETS);
|
||||
if (local_debug) fprintf(stderr, "findTransactionCacheEntry: hash=%lu\n", hash);
|
||||
struct entry **bucket = &buckets[hash];
|
||||
if (local_debug) fprintf(stderr, "findTransactionCacheEntry: bucket=%p\n", bucket);
|
||||
struct entry *e = *bucket;
|
||||
if (local_debug) fprintf(stderr, "findTransactionCacheEntry: e=%p\n", e);
|
||||
while (e && memcmp(e->transaction_id, transaction_id, TRANSID_SIZE) != 0) {
|
||||
e = e->bucket_next;
|
||||
if (local_debug) fprintf(stderr, "findTransactionCacheEntry: e=%p\n", e);
|
||||
}
|
||||
return e;
|
||||
}
|
||||
@ -98,7 +110,11 @@ static void lru_insert_head(struct entry *e)
|
||||
{
|
||||
e->lru_next = lru_head;
|
||||
e->lru_prev = NULL;
|
||||
lru_head->lru_prev = e;
|
||||
if (lru_head) {
|
||||
lru_head->lru_prev = e;
|
||||
} else {
|
||||
lru_tail = e;
|
||||
}
|
||||
lru_head = e;
|
||||
}
|
||||
|
||||
@ -126,6 +142,7 @@ static void lru_remove(struct entry *e)
|
||||
*/
|
||||
static void evict()
|
||||
{
|
||||
if (local_debug) fprintf(stderr, "evict() lru_tail=%p\n", lru_tail);
|
||||
if (lru_tail) {
|
||||
struct entry *e = lru_tail;
|
||||
lru_remove(e);
|
||||
@ -146,20 +163,25 @@ static void evict()
|
||||
*/
|
||||
void insertTransactionInCache(unsigned char *transaction_id)
|
||||
{
|
||||
if (local_debug) fprintf(stderr, "insertTransactionInCache(%llx)\n", *(long long unsigned*)transaction_id);
|
||||
size_t hash = hashTransactionId(transaction_id, TRANS_CACHE_BUCKETS);
|
||||
if (local_debug) fprintf(stderr, "findTransactionCacheEntry: hash=%lu\n", hash);
|
||||
if (!entry_freelist) {
|
||||
init_pool();
|
||||
}
|
||||
if (!entry_freelist) {
|
||||
init_trans_cache();
|
||||
evict();
|
||||
}
|
||||
if (local_debug) fprintf(stderr, "findTransactionCacheEntry: entry_freelist=%p\n", entry_freelist);
|
||||
struct entry *e = entry_freelist;
|
||||
if (local_debug) fprintf(stderr, "findTransactionCacheEntry: entry_freelist->bucket_next=%p\n", entry_freelist->bucket_next);
|
||||
entry_freelist = e->bucket_next;
|
||||
memcpy(e->transaction_id, transaction_id, TRANSID_SIZE);
|
||||
struct entry **bucket = &buckets[hash];
|
||||
if (local_debug) fprintf(stderr, "findTransactionCacheEntry: bucket=%p\n", bucket);
|
||||
if (local_debug) fprintf(stderr, "findTransactionCacheEntry: *bucket=%p\n", *bucket);
|
||||
e->bucket_next = *bucket;
|
||||
lru_insert_head(e);
|
||||
*bucket = e;
|
||||
lru_insert_head(e);
|
||||
if (local_debug) fprintf(stderr, "insertTransactionInCache done\n");
|
||||
}
|
||||
|
||||
/* Return TRUE if the given transaction ID is in the cache. If it is, promote
|
||||
@ -169,6 +191,7 @@ void insertTransactionInCache(unsigned char *transaction_id)
|
||||
*/
|
||||
int isTransactionInCache(unsigned char *transaction_id)
|
||||
{
|
||||
if (local_debug) fprintf(stderr, "isTransactionInCache(%llx)\n", *(long long unsigned*)transaction_id);
|
||||
struct entry *e = findTransactionCacheEntry(transaction_id);
|
||||
if (e && e != lru_head) {
|
||||
lru_remove(e);
|
||||
|
Loading…
x
Reference in New Issue
Block a user