Fix another manifest leak

Add manifest alloc/free debug logging to help, 'debug.manifests' option
This commit is contained in:
Andrew Bettison 2012-05-25 17:01:56 +09:30
parent 214d20f27e
commit bea9188cd5
6 changed files with 35 additions and 19 deletions

1
log.c
View File

@ -148,6 +148,7 @@ long long debugFlagMask(const char *flagname) {
else if (!strcasecmp(flagname,"monitorroutes")) return DEBUG_OVERLAYROUTEMONITOR; else if (!strcasecmp(flagname,"monitorroutes")) return DEBUG_OVERLAYROUTEMONITOR;
else if (!strcasecmp(flagname,"queues")) return DEBUG_QUEUES; else if (!strcasecmp(flagname,"queues")) return DEBUG_QUEUES;
else if (!strcasecmp(flagname,"broadcasts")) return DEBUG_BROADCASTS; else if (!strcasecmp(flagname,"broadcasts")) return DEBUG_BROADCASTS;
else if (!strcasecmp(flagname,"manifests")) return DEBUG_MANIFESTS;
WARNF("Unsupported debug flag '%s'", flagname); WARNF("Unsupported debug flag '%s'", flagname);
return 0; return 0;
} }

View File

@ -247,7 +247,7 @@ int rhizome_update_file_priority(char *fileid);
int rhizome_find_duplicate(const rhizome_manifest *m, rhizome_manifest **found); int rhizome_find_duplicate(const rhizome_manifest *m, rhizome_manifest **found);
int rhizome_manifest_to_bar(rhizome_manifest *m,unsigned char *bar); int rhizome_manifest_to_bar(rhizome_manifest *m,unsigned char *bar);
char nybltochar_upper(int n); char nybltochar_upper(int n);
int rhizome_queue_manifest_import(rhizome_manifest *m,struct sockaddr_in *peerip); int rhizome_queue_manifest_import(rhizome_manifest *m, struct sockaddr_in *peerip, int *manifest_kept);
int rhizome_list_manifests(const char *service, const char *sender_sid, const char *recipient_sid, int limit, int offset); int rhizome_list_manifests(const char *service, const char *sender_sid, const char *recipient_sid, int limit, int offset);
int rhizome_retrieve_manifest(const char *manifestid, rhizome_manifest **mp); int rhizome_retrieve_manifest(const char *manifestid, rhizome_manifest **mp);
int rhizome_retrieve_file(const char *fileid, const char *filepath); int rhizome_retrieve_file(const char *fileid, const char *filepath);

View File

@ -288,6 +288,16 @@ const char *manifest_free_sourcefiles[MAX_RHIZOME_MANIFESTS];
const char *manifest_free_functions[MAX_RHIZOME_MANIFESTS]; const char *manifest_free_functions[MAX_RHIZOME_MANIFESTS];
int manifest_free_lines[MAX_RHIZOME_MANIFESTS]; int manifest_free_lines[MAX_RHIZOME_MANIFESTS];
static void _log_manifest_trace(const char *filename, const char *funcname, int line, const char *operation)
{
int count_free = 0;
int i;
for (i = 0; i != MAX_RHIZOME_MANIFESTS; ++i)
if (manifest_free[i])
++count_free;
logMessage(LOG_LEVEL_DEBUG, filename, line, funcname, "%s(): count_free = %d", operation, count_free);
}
rhizome_manifest *_rhizome_new_manifest(const char *filename, const char *funcname, int line) rhizome_manifest *_rhizome_new_manifest(const char *filename, const char *funcname, int line)
{ {
if (manifest_first_free<0) { if (manifest_first_free<0) {
@ -337,10 +347,10 @@ rhizome_manifest *_rhizome_new_manifest(const char *filename, const char *funcna
manifest_free_lines[manifest_first_free]=-1; manifest_free_lines[manifest_first_free]=-1;
/* Work out where next free manifest record lives */ /* Work out where next free manifest record lives */
for(;manifest_first_free<MAX_RHIZOME_MANIFESTS for (; manifest_first_free < MAX_RHIZOME_MANIFESTS && !manifest_free[manifest_first_free]; ++manifest_first_free)
&&(!manifest_free[manifest_first_free]); ;
manifest_first_free++)
continue; if (debug & DEBUG_MANIFESTS) _log_manifest_trace(filename, funcname, line, __FUNCTION__);
return m; return m;
} }
@ -390,6 +400,8 @@ void _rhizome_manifest_free(const char *sourcefile,const char *funcname,int line
manifest_free_lines[mid]=line; manifest_free_lines[mid]=line;
if (mid<manifest_first_free) manifest_first_free=mid; if (mid<manifest_first_free) manifest_first_free=mid;
if (debug & DEBUG_MANIFESTS) _log_manifest_trace(sourcefile, funcname, line, __FUNCTION__);
return; return;
} }

View File

@ -378,13 +378,12 @@ int rhizome_suggest_queue_manifest_import(rhizome_manifest *m,
(also replace older manifest versions with newer ones, (also replace older manifest versions with newer ones,
which can upset the ordering.) */ which can upset the ordering.) */
if (candidates[i].manifest==NULL) continue; if (candidates[i].manifest==NULL) continue;
if (!strcmp(id,rhizome_manifest_get(candidates[i].manifest,"id",NULL,0))) if (!strcasecmp(id,rhizome_manifest_get(candidates[i].manifest,"id",NULL,0)))
{ {
/* duplicate. /* duplicate.
XXX - Check versions! We should replace older with newer, XXX - Check versions! We should replace older with newer,
and then update position in queue based on size */ and then update position in queue based on size */
long long list_version=rhizome_manifest_get_ll(candidates[i].manifest, long long list_version=rhizome_manifest_get_ll(candidates[i].manifest, "version");
"version");
long long this_version=rhizome_manifest_get_ll(m,"version"); long long this_version=rhizome_manifest_get_ll(m,"version");
if (list_version>=this_version) { if (list_version>=this_version) {
/* this version is older than the one in the list, /* this version is older than the one in the list,
@ -452,8 +451,12 @@ int rhizome_enqueue_suggestions()
{ {
if (rhizome_file_fetch_queue_count>=MAX_QUEUED_FILES) if (rhizome_file_fetch_queue_count>=MAX_QUEUED_FILES)
break; break;
rhizome_queue_manifest_import(candidates[i].manifest,&candidates[i].peer); int manifest_kept = 0;
candidates[i].manifest=NULL; rhizome_queue_manifest_import(candidates[i].manifest,&candidates[i].peer, &manifest_kept);
if (!manifest_kept) {
rhizome_manifest_free(candidates[i].manifest);
candidates[i].manifest = NULL;
}
} }
if (i) { if (i) {
/* now shuffle up */ /* now shuffle up */
@ -467,8 +470,9 @@ int rhizome_enqueue_suggestions()
return 0; return 0;
} }
int rhizome_queue_manifest_import(rhizome_manifest *m, struct sockaddr_in *peerip) int rhizome_queue_manifest_import(rhizome_manifest *m, struct sockaddr_in *peerip, int *manifest_kept)
{ {
*manifest_kept = 0;
int i; int i;
/* Do the quick rejection tests first, before the more expensive once, /* Do the quick rejection tests first, before the more expensive once,
@ -580,7 +584,8 @@ int rhizome_queue_manifest_import(rhizome_manifest *m, struct sockaddr_in *peeri
rhizome_file_fetch_record rhizome_file_fetch_record
*q=&file_fetch_queue[rhizome_file_fetch_queue_count]; *q=&file_fetch_queue[rhizome_file_fetch_queue_count];
q->manifest=m; q->manifest = m;
*manifest_kept = 1;
q->socket=sock; q->socket=sock;
strncpy(q->fileid, m->fileHexHash, RHIZOME_FILEHASH_STRLEN + 1); strncpy(q->fileid, m->fileHexHash, RHIZOME_FILEHASH_STRLEN + 1);
snprintf(q->request,1024,"GET /rhizome/file/%s HTTP/1.0\r\n\r\n", snprintf(q->request,1024,"GET /rhizome/file/%s HTTP/1.0\r\n\r\n",

View File

@ -402,8 +402,7 @@ int overlay_rhizome_saw_advertisements(int i,overlay_frame *f, long long now)
rhizome_queue_ignore_manifest(m,(struct sockaddr_in*)f->recvaddr,60000); rhizome_queue_ignore_manifest(m,(struct sockaddr_in*)f->recvaddr,60000);
} }
if (m) rhizome_manifest_free(m); if (m) rhizome_manifest_free(m);
m=NULL; m=NULL;
if (importManifest) { if (importManifest) {
/* Okay, so the manifest looks like it is potentially interesting to us, /* Okay, so the manifest looks like it is potentially interesting to us,
i.e., we don't already have it or a later version of it. i.e., we don't already have it or a later version of it.
@ -412,29 +411,27 @@ int overlay_rhizome_saw_advertisements(int i,overlay_frame *f, long long now)
WHY("Out of manifests"); WHY("Out of manifests");
else if (rhizome_read_manifest_file(m, (char *)&f->payload->bytes[ofs], manifest_length, RHIZOME_VERIFY) == -1) { else if (rhizome_read_manifest_file(m, (char *)&f->payload->bytes[ofs], manifest_length, RHIZOME_VERIFY) == -1) {
WHY("Error importing manifest body"); WHY("Error importing manifest body");
rhizome_manifest_free(m); rhizome_manifest_free(m);
m = NULL; m = NULL;
} else if (m->errors) { } else if (m->errors) {
if (debug&DEBUG_RHIZOME) DEBUGF("Verifying manifest %s revealed errors -- not storing.", manifest_id); if (debug&DEBUG_RHIZOME) DEBUGF("Verifying manifest %s revealed errors -- not storing.", manifest_id);
rhizome_queue_ignore_manifest(m,(struct sockaddr_in*)f->recvaddr,60000); rhizome_queue_ignore_manifest(m,(struct sockaddr_in*)f->recvaddr,60000);
rhizome_manifest_free(m); rhizome_manifest_free(m);
m = NULL; m = NULL;
} else { } else {
if (debug&DEBUG_RHIZOME) DEBUGF("Verifying manifest %s revealed no errors -- will try to store.", manifest_id); if (debug&DEBUG_RHIZOME) DEBUGF("Verifying manifest %s revealed no errors -- will try to store.", manifest_id);
/* Add manifest to import queue. We need to know originating IPv4 address /* Add manifest to import queue. We need to know originating IPv4 address
so that we can transfer by HTTP. */ so that we can transfer by HTTP. */
if (0) DEBUG("Suggesting fetching of a bundle"); if (0) DEBUG("Suggesting fetching of a bundle");
rhizome_suggest_queue_manifest_import(m,(struct sockaddr_in *)f->recvaddr); rhizome_suggest_queue_manifest_import(m,(struct sockaddr_in *)f->recvaddr);
} }
} }
if (!manifest_length) { if (!manifest_length) {
WHY("Infinite loop in packet decoding"); WHY("Infinite loop in packet decoding");
break; break;
} }
ofs+=manifest_length; ofs+=manifest_length;
} }
} }
return 0; return 0;

View File

@ -1073,6 +1073,7 @@ int overlay_saw_mdp_containing_frame(int interface,overlay_frame *f,long long no
#define DEBUG_RHIZOMESYNC (1 << 21) #define DEBUG_RHIZOMESYNC (1 << 21)
#define DEBUG_PACKETTX (1 << 22) #define DEBUG_PACKETTX (1 << 22)
#define DEBUG_PACKETCONSTRUCTION (1 << 23) #define DEBUG_PACKETCONSTRUCTION (1 << 23)
#define DEBUG_MANIFESTS (1 << 24)
int serval_packetvisualise(FILE *f,char *message,unsigned char *packet,int plen); int serval_packetvisualise(FILE *f,char *message,unsigned char *packet,int plen);