int StringChunk_Add(StringChunk *dl, const char *Str, const char *AdditionalData, int LengthOfAdditionalData /* The length will not be stored. */ ) { EntryForString NewEntry; if( AdditionalData != NULL && LengthOfAdditionalData > 0 ) { _32BIT_INT OffsetOfStoredTo; char *DataStoredTo = ExtendableBuffer_Expand(&(dl -> AdditionalDataChunk), LengthOfAdditionalData, &OffsetOfStoredTo ); if( DataStoredTo == NULL ) { return -1; } NewEntry.OffsetOfData = OffsetOfStoredTo; memcpy(DataStoredTo, AdditionalData, LengthOfAdditionalData); } else { NewEntry.OffsetOfData = -1; } if( ContainWildCard(Str) ) { NewEntry.OffsetOfString = StringList_Add(&(dl -> List_W), Str, ','); if( NewEntry.OffsetOfString >= 0 ) { Array_PushBack(&(dl -> List_W_Pos), &NewEntry, NULL); } else { return -1; } } else { NewEntry.OffsetOfString = StringList_Add(&(dl -> List), Str, ','); if( NewEntry.OffsetOfString >= 0 ) { HashTable_Add(&(dl -> List_Pos), Str, 0, &NewEntry, NULL); } else { return -2; } } return 0; }
int DNSFetchFromCache(__in ThreadContext *Context) { int RecordsCount, RecordsLength; char *Header; int32_t HeaderOffset; Header = ExtendableBuffer_Expand(Context -> ResponseBuffer, Context -> RequestLength, &HeaderOffset); if( Header == NULL ) { return -1; } memcpy(Header, Context -> RequestEntity, Context -> RequestLength); ((DNSHeader *)Header) -> Flags.Direction = 1; ((DNSHeader *)Header) -> Flags.AuthoritativeAnswer = 0; ((DNSHeader *)Header) -> Flags.RecursionAvailable = 1; ((DNSHeader *)Header) -> Flags.ResponseCode = 0; ((DNSHeader *)Header) -> Flags.Type = 0; RecordsCount = DNSCache_GetByQuestion(Context -> RequestEntity, Context -> ResponseBuffer, &RecordsLength, Context -> CurrentTime); if( RecordsCount > 0 ) { Header = ExtendableBuffer_GetData(Context -> ResponseBuffer) + HeaderOffset; ((DNSHeader *)Header) -> AnswerCount = htons(RecordsCount); if(Context -> Compress != FALSE) { int UnCompressedLength = Context -> RequestLength + RecordsLength; int CompressedLength = DNSCompress(Header, UnCompressedLength); ExtendableBuffer_Eliminate_Tail(Context -> ResponseBuffer, UnCompressedLength - CompressedLength); ShowNormalMassage(Context, HeaderOffset, 'C'); return CompressedLength; } else { ShowNormalMassage(Context, HeaderOffset, 'C'); return Context -> RequestLength + RecordsLength; } } else { return -1; } }
int DNSFetchFromHosts(__in ThreadContext *Context) { char *Header; int RecordsLength; int32_t HeaderOffset; int AnswerCount; Header = ExtendableBuffer_Expand(Context -> ResponseBuffer, Context -> RequestLength, &HeaderOffset); if( Header == NULL ) { return -1; } RecordsLength = DynamicHosts_GetByQuestion(Context, &AnswerCount); if( RecordsLength > 0 ) { Header = ExtendableBuffer_GetData(Context -> ResponseBuffer) + HeaderOffset; memcpy(Header, Context -> RequestEntity, Context -> RequestLength); ((DNSHeader *)Header) -> Flags.Direction = 1; ((DNSHeader *)Header) -> Flags.AuthoritativeAnswer = 0; ((DNSHeader *)Header) -> Flags.RecursionAvailable = 0; ((DNSHeader *)Header) -> Flags.ResponseCode = 0; ((DNSHeader *)Header) -> AnswerCount = htons(AnswerCount); if( AnswerCount != 1 && Context -> Compress != FALSE ) { int UnCompressedLength = Context -> RequestLength + RecordsLength; int CompressedLength = DNSCompress(Header, UnCompressedLength); ExtendableBuffer_Eliminate_Tail(Context -> ResponseBuffer, UnCompressedLength - CompressedLength); ShowNormalMassage(Context, HeaderOffset, 'H'); return CompressedLength; } else { ShowNormalMassage(Context, HeaderOffset, 'H'); return Context -> RequestLength + RecordsLength; } } else { return -1; } }
static int StaticHosts_GenerateSingleRecord(DNSRecordType Type, const char *IPOrCName, ExtendableBuffer *Buffer) { char *HereSaved; int RecordLength; switch( Type ) { case DNS_TYPE_A: RecordLength = 2 + 2 + 2 + 4 + 2 + 4; break; case DNS_TYPE_AAAA: RecordLength = 2 + 2 + 2 + 4 + 2 + 16; break; case DNS_TYPE_CNAME: RecordLength = 2 + 2 + 2 + 4 + 2 + strlen(IPOrCName) + 2; break; default: return -1; break; } HereSaved = ExtendableBuffer_Expand(Buffer, RecordLength, NULL); if( HereSaved == NULL ) { return -1; } DNSGenResourceRecord(HereSaved + 1, INT_MAX, "", Type, DNS_CLASS_IN, 60, IPOrCName, 4, FALSE); HereSaved[0] = 0xC0; HereSaved[1] = 0x0C; return RecordLength; }
static int Hosts_RecursivelyQuery(const char *IPOrCName, int *AnswerCount, ThreadContext *Context) { int PrependLength = 2 + 2 + 2 + 4 + 2 + strlen(IPOrCName) + 2; BOOL OriCompress = Context -> Compress; int State; int StartOffset = ExtendableBuffer_GetEndOffset(Context -> ResponseBuffer); char *StartPos; int EndOffset; const char *AnswerPos; int MoreSpaceNeeded = 0; char *HereSaved; HereSaved = ExtendableBuffer_Expand(Context -> ResponseBuffer, PrependLength, NULL); if( HereSaved == NULL ) { return -1; } Context -> Compress = FALSE; DNSGenResourceRecord(HereSaved + 1, INT_MAX, "", DNS_TYPE_CNAME, DNS_CLASS_IN, 60, IPOrCName, strlen(IPOrCName) + 1, TRUE); HereSaved[0] = 0xC0; HereSaved[1] = 0x0C; StartOffset = ExtendableBuffer_GetEndOffset(Context -> ResponseBuffer); State = GetAnswersByName(Context, IPOrCName, Context -> RequestingType, "CNameRedirect"); if( State < 0 ) { Context -> Compress = OriCompress; return -1; } StartPos = ExtendableBuffer_GetPositionByOffset(Context -> ResponseBuffer, StartOffset); EndOffset = DNSJumpOverAnswerRecords(StartPos) - ExtendableBuffer_GetData(Context -> ResponseBuffer); (*AnswerCount) = (int)DNSGetAnswerCount(StartPos) + 1; ExtendableBuffer_Eliminate(Context -> ResponseBuffer, EndOffset, StartOffset + State - EndOffset); MoreSpaceNeeded = DNSExpandCName_MoreSpaceNeeded(StartPos); if( ExtendableBuffer_Expand(Context -> ResponseBuffer, MoreSpaceNeeded, NULL) == NULL ) { Context -> Compress = OriCompress; return -1; } EndOffset += MoreSpaceNeeded; StartPos = ExtendableBuffer_GetPositionByOffset(Context -> ResponseBuffer, StartOffset); DNSExpandCName(StartPos); AnswerPos = DNSJumpOverQuestionRecords(StartPos); ExtendableBuffer_Eliminate(Context -> ResponseBuffer, StartOffset, AnswerPos - StartPos); Context -> Compress = OriCompress; return EndOffset - StartOffset - (AnswerPos - StartPos) + PrependLength; }