Various fixes and addition of memory corruption framework (not yet active).

Rhizome now advertises all manifests, instead of accidently skipping some.
This commit is contained in:
gardners 2012-02-15 23:38:23 +10:30
parent 9a65f6c995
commit ce2afbe2ab
5 changed files with 112 additions and 34 deletions

10
mphlr.h
View File

@ -916,4 +916,14 @@ int overlay_broadcast_drop_check(unsigned char *a);
int overlay_address_is_broadcast(unsigned char *a);
int overlay_broadcast_generate_address(unsigned char *a);
int overlay_abbreviate_unset_current_sender();
int rhizome_fetching_get_fds(struct pollfd *fds,int *fdcount,int fdmax);
int rhizome_fetch_poll();
#define DEBUG_MEM_ABUSE
#ifdef DEBUG_MEM_ABUSE
int memabuseInit();
int memabuseCheck(char *func,char *file,int line);
#else
#define memabuseInit() /* */
#define memabuseCheck(A,B,C) /* */
#endif

View File

@ -104,7 +104,6 @@ int overlay_route_add_advertisements(int interface,overlay_buffer *e)
ob_append_byte(e,OA_CODE_PREVIOUS);
ob_append_byte(e,OA_CODE_SELF);
int count;
while (slots>0&&oad_request_count) {
oad_request_count--;
ob_append_bytes(e,oad_requests[oad_request_count]->sid,6);

View File

@ -162,8 +162,6 @@ int overlay_rhizome_add_advertisements(int interface_number,overlay_buffer *e)
while((bytes_used<bytes_available)&&(sqlite3_step(statement)==SQLITE_ROW)&&
(e->length+RHIZOME_BAR_BYTES<=e->sizeLimit))
{
fprintf(stderr,"pass=%d, rowid=%lld\n",
pass,sqlite3_column_int64(statement,1));
sqlite3_blob *blob;
int column_type=sqlite3_column_type(statement, 0);
switch(column_type) {
@ -191,12 +189,13 @@ int overlay_rhizome_add_advertisements(int interface_number,overlay_buffer *e)
}
int overhead=0;
int frameFull=0;
if (!pass) overhead=2;
if (ob_makespace(e,overhead+blob_bytes)) {
if (debug&DEBUG_RHIZOME)
fprintf(stderr,"Stopped cramming %s into Rhizome advertisement frame.\n",
pass?"BARs":"manifests");
goto stopStuffing;
frameFull=1;
}
if (!pass) {
/* put manifest length field and manifest ID */
@ -205,8 +204,17 @@ int overlay_rhizome_add_advertisements(int interface_number,overlay_buffer *e)
if (debug&DEBUG_RHIZOME)
fprintf(stderr,"length bytes written at offset 0x%x\n",e->length);
}
if (frameFull) {
goto stopStuffing;
}
if (sqlite3_blob_read(blob,&e->bytes[e->length+overhead],blob_bytes,0)
!=SQLITE_OK) {
if (!pass) {
fprintf(stderr," Manifest:\n");
int i;
for(i=0;i<blob_bytes;i++) fprintf(stderr,"%c",e->bytes[e->length+overhead+i]);
}
if (debug&DEBUG_RHIZOME) WHY("Couldn't read from blob");
sqlite3_blob_close(blob);
continue;
@ -214,23 +222,22 @@ int overlay_rhizome_add_advertisements(int interface_number,overlay_buffer *e)
e->length+=overhead+blob_bytes;
bytes_used+=overhead+blob_bytes;
bundles_advertised++;
bundle_offset[pass]=sqlite3_column_int64(statement,1)+1;
bundle_offset[pass]=sqlite3_column_int64(statement,1);
sqlite3_blob_close(blob);
}
}
sqlite3_finalize(statement);
stopStuffing:
if (!pass)
{
/* Mark end of whole manifests by writing 0xff, which is more than the MSB
of a manifest's length is allowed to be. */
ob_append_byte(e,0xff);
}
stopStuffing:
continue;
}
if (debug&DEBUG_RHIZOME) printf("Appended %d rhizome advertisements to packet.\n",bundles_advertised);
if (debug&DEBUG_RHIZOME) printf("Appended %d rhizome advertisements to packet using %d bytes.\n",bundles_advertised,bytes_used);
int rfs_value=1+8+1+1+1+bytes_used;
if (rfs_value<0xfa)
e->bytes[rfs_offset]=rfs_value;
@ -268,7 +275,11 @@ int overlay_rhizome_saw_advertisements(int i,overlay_frame *f, long long now)
if (manifest_length>=0xff00) {
ofs++;
break;
}
}
if (ofs+manifest_length>f->payload->length) {
WHY("Illegal manifest length field in rhizome advertisement frame.");
break;
}
ofs+=2;
if (manifest_length==0) continue;
@ -325,7 +336,7 @@ int overlay_rhizome_saw_advertisements(int i,overlay_frame *f, long long now)
/* Add manifest to import queue. We need to know originating IPv4 address
so that we can transfer by HTTP. */
if (rhizome_queue_manifest_import(m,f->recvaddr))
if (rhizome_queue_manifest_import(m,(struct sockaddr_in *)f->recvaddr))
rhizome_manifest_free(m);
}
}

View File

@ -296,9 +296,26 @@ int isOverlayPacket(FILE *f,unsigned char *packet,int *ofs,int len)
/* Check for end of manifests */
if (manifest_len>=0xff00) { i+=1; break; }
else i+=2;
if (manifest_len>(frame_len-i)) {
fprintf(f,"%sERROR: Manifest extends for 0x%x bytes, but frame contains only 0x%x more bytes -- skipping rest of frame.\n",indent(10),manifest_len,frame_len-i);
int j;
for(;i<frame_len;i+=16)
{
fprintf(f,"%s%04x :",indent(12),i);
for(j=0;j<16&&(i+j)<frame_len;j++) fprintf(f," %02x",frame[i+j]);
for(;j<16;j++) fprintf(f," ");
fprintf(f," ");
for(j=0;j<16&&(i+j)<frame_len;j++) fprintf(f,"%c",frame[i+j]>=' '
&&frame[i+j]<0x7c?frame[i+j]:'.');
fprintf(f,"\n");
}
i=frame_len;
break;
}
/* find manifest self-signature block */
for(j=0;j<manifest_len;j++) if (frame[i+j]==0) { j++; break;}
fprintf(f,"%smanifest id (from first signature block) = ",indent(10));
fprintf(f,"%smanifest id @0x%x-0x%x/0x%x (len=0x%x) (from first signature block) = ",
indent(10),i,i+manifest_len-1,frame_len,manifest_len);
for(k=0;k<32;k++) fprintf(f,"%02X",frame[i+j+k+1+64]);
fprintf(f,"\n");
/* Print manifest text body */

View File

@ -59,30 +59,35 @@ int recvwithttl(int sock,unsigned char *buffer,int bufferlen,int *ttl,
fcntl(sock,F_SETFL, O_NONBLOCK);
int len = recvmsg(sock,&msg,0);
if (debug&DEBUG_PACKETXFER)
fprintf(stderr,"recvmsg returned %d bytes (flags=%d,msg_controllen=%d)\n",
len,msg.msg_flags,msg.msg_controllen);
fprintf(stderr,"recvmsg returned %d bytes (flags=%d,msg_controllen=%d)\n",
len,msg.msg_flags,msg.msg_controllen);
if (len>0) {
struct cmsghdr *cmsg;
for (cmsg = CMSG_FIRSTHDR(&msg);
cmsg != NULL;
cmsg = CMSG_NXTHDR(&msg,cmsg)) {
if ((cmsg->cmsg_level == IPPROTO_IP) &&
((cmsg->cmsg_type == IP_RECVTTL) ||(cmsg->cmsg_type == IP_TTL))
&&(cmsg->cmsg_len) ){
fprintf(stderr," TTL (%p) data location resolves to %p\n",
ttl,CMSG_DATA(cmsg));
if (CMSG_DATA(cmsg)) {
*ttl = *(unsigned char *) CMSG_DATA(cmsg);
fprintf(stderr," TTL of packet is %d\n",*ttl);
}
} else {
fprintf(stderr,"I didn't expect to see level=%02x, type=%02x\n",
cmsg->cmsg_level,cmsg->cmsg_type);
}
}
struct cmsghdr *cmsg;
if (len>0)
{
for (cmsg = CMSG_FIRSTHDR(&msg);
cmsg != NULL;
cmsg = CMSG_NXTHDR(&msg,cmsg)) {
if ((cmsg->cmsg_level == IPPROTO_IP) &&
((cmsg->cmsg_type == IP_RECVTTL) ||(cmsg->cmsg_type == IP_TTL))
&&(cmsg->cmsg_len) ){
if (debug&DEBUG_PACKETXFER)
fprintf(stderr," TTL (%p) data location resolves to %p\n",
ttl,CMSG_DATA(cmsg));
if (CMSG_DATA(cmsg)) {
*ttl = *(unsigned char *) CMSG_DATA(cmsg);
if (debug&DEBUG_PACKETXFER)
fprintf(stderr," TTL of packet is %d\n",*ttl);
}
} else {
if (debug&DEBUG_PACKETXFER)
fprintf(stderr,"I didn't expect to see level=%02x, type=%02x\n",
cmsg->cmsg_level,cmsg->cmsg_type);
}
}
}
*recvaddrlen=msg.msg_namelen;
@ -655,3 +660,39 @@ int simpleServerMode()
}
return 0;
}
#ifdef DEBUG_MEM_ABUSE
unsigned char groundzero[65536];
int memabuseInit()
{
unsigned char *zero=(unsigned char *)0;
int i;
for(i=0;i<65536;i++) groundzero[i]=zero[i];
return 0;
}
int memabuseCheck(char *func,char *file,int line)
{
unsigned char *zero=(unsigned char *)0;
int firstAddr=-1;
int lastAddr=-1;
int i;
for(i=0;i<65536;i++) if (groundzero[i]!=zero[i]) {
lastAddr=i;
if (firstAddr==-1) firstAddr=i;
}
if (lastAddr>0) {
fprintf(stderr,"WARNING: Memory corruption in first 64KB of RAM detected.\n");
fprintf(stderr," Changed bytes exist in range 0x%04x - 0x%04x\n",firstAddr,lastAddr);
dump("Changed memory content",&zero[firstAddr],lastAddr-firstAddr+1);
dump("Initial memory content",&groundzero[firstAddr],lastAddr-firstAddr+1);
sleep(1);
} else {
fprintf(stderr,"All's well at %s() %s:%d\n",func,file,line);
}
return 0;
}
#endif