/* updates user_tag (should be constructed) with all channels digests */ static void ChannelsDigest(struct NaClApp *nap) { int i; assert(nap != NULL); for(i = 0; i < nap->system_manifest->channels_count; ++i) TagUpdate(nap->user_tag, (const char*) nap->system_manifest->channels[i].digest, TAG_DIGEST_SIZE); }
/* updates channel tag */ static void UpdateChannelTag(struct ChannelDesc *channel, const char *buffer, int32_t size) { /* skip if etag is not enabled */ if(!CHANNELS_ETAG_ENABLED) return; assert(channel != NULL); assert(buffer != NULL); /* update etag and log information */ if(size <= 0) return; TagUpdate(channel->tag, buffer, size); }
/* updates user_tag (should be constructed) with memory chunk data */ static void EtagMemoryChunk(struct NaClApp *nap) { int i; assert(nap != NULL); assert(MEMORY_ETAG_ENABLED != 0); for(i = 0; i < MemMapSize; ++i) { uintptr_t addr = nap->mem_map[i].start; int64_t size = nap->mem_map[i].size; /* update user_etag skipping inaccessible pages */ if(nap->mem_map[i].prot & PROT_READ) TagUpdate(nap->user_tag, (const char*) addr, size); } }
/* calculate user memory tag, and return pointer to it */ static void *GetMemoryDigest(struct NaClApp *nap) { int i; assert(nap != NULL); /* calculate overall memory tag */ for(i = 0; i < MemMapSize; ++i) { uintptr_t addr = nap->mem_map[i].start; int64_t size = nap->mem_map[i].size; /* update user_etag skipping inaccessible pages */ if(nap->mem_map[i].prot & PROT_READ) TagUpdate(nap->manifest->mem_tag, (const char*)addr, size); } return nap->manifest->mem_tag; }
/* updates user_tag (should be constructed) with memory chunk data */ static void EtagMemoryChunk(struct NaClApp *nap) { int i; assert(nap != NULL); assert(TagEngineEnabled() != 0); for(i = 0; i < MemMapSize; ++i) { uintptr_t addr; int32_t size; /* skip inaccessible pages */ if(nap->mem_map[RODataIdx].prot == PROT_NONE) continue; /* update user_etag with the chunk data */ addr = nap->mem_map[RODataIdx].page_num << NACL_PAGESHIFT; size = nap->mem_map[RODataIdx].npages << NACL_PAGESHIFT; TagUpdate(nap->user_tag, (const char*)addr, size); } }
int PrefetchChannelDtor(struct ChannelDesc *channel) { char url[BIG_ENOUGH_STRING]; /* debug purposes only */ assert(channel != NULL); assert(channel->socket != NULL); /* log parameters and channel internals */ MakeURL(url, BIG_ENOUGH_STRING, channel, GetChannelConnectionInfo(channel)); ZLOGS(LOG_DEBUG, "%s has url %s", channel->alias, url); /* close "PUT" channel */ if(channel->limits[PutsLimit] && channel->limits[PutSizeLimit]) { int size = CHANNELS_ETAG_ENABLED ? TAG_DIGEST_SIZE - 1 : 0; /* prepare digest */ if(TagEngineEnabled()) { TagDigest(channel->tag, channel->digest); TagDtor(channel->tag); } /* send eof */ channel->eof = 1; SendMessage(channel, channel->digest, size); ZLOGS(LOG_DEBUG, "%s closed with tag %s, putsize %ld", channel->alias, channel->digest, channel->counters[PutSizeLimit]); } /* close "GET" channel */ if(channel->limits[GetsLimit] && channel->limits[GetSizeLimit]) { /* wind the channel to the end */ while(channel->eof == 0) { char buf[NET_BUFFER_SIZE]; int32_t size = FetchMessage(channel, buf, NET_BUFFER_SIZE); ++channel->counters[GetsLimit]; channel->counters[GetSizeLimit] += size; /* update tag if enabled */ if(TagEngineEnabled()) TagUpdate(channel->tag, buf, size); } /* test integrity (if etag enabled) */ if(TagEngineEnabled()) { /* prepare digest */ TagDigest(channel->tag, channel->digest); TagDtor(channel->tag); /* raise the error if the data corrupted */ if(memcmp(channel->control, channel->digest, TAG_DIGEST_SIZE) != 0) { ZLOG(LOG_ERROR, "%s corrupted, control: %s, local: %s", channel->alias, channel->control, channel->digest); SetExitState("data corrupted"); SetExitCode(EPIPE); } ZLOGS(LOG_DEBUG, "%s closed with tag %s, getsize %ld", channel->alias, channel->digest, channel->counters[GetSizeLimit]); } zmq_msg_close(&channel->msg); zmq_close(channel->socket); } /* will destroy context and netlist after all network channels closed */ NetDtor(); return 0; }