void SVUnixOpMonitor::telnet_protocol(SOCKET server,unsigned char code,LPGDATA pgd) { int i = 0; switch(state) { case state_data: switch(code) { case IAC: state = state_code; break; default: DataProc(server,code,pgd); } break; case state_code: state = state_data; switch(code) { // State transition back to data case IAC: DataProc(server,code,pgd); break; // Code state transitions back to data case SE: DataProc = terminal[(pgd->term_index==NUM_TERMINALS)?(NUM_TERMINALS-1):pgd->term_index].termproc; break; case NOP: break; case DM: break; case BRK: break; case IP: break; case AO: break; case AYT: break; case EC: break; case EL: break; case GA: break; // Transitions to option state case SB: verb = verb_sb; state = state_option; break; case WILL: verb = verb_will; state = state_option; break; case WONT: verb = verb_wont; state = state_option; break; case DO: verb = verb_do; state = state_option; break; case DONT: verb = verb_dont; state = state_option; break; } break; case state_option: state = state_data; //Find the option entry for(;ol[i].option != TOPT_ERROR && ol[i].option != code;i++); //Do some verb specific stuff if(verb == verb_sb) DataProc = ol[i].DataProc; else ol[i].OptionProc(server,verb,(_option)code); break; } }
size_t Http2Base::DefaultProc(const uchar* http2_buff, size_t len) { const Http2_header *header = (const Http2_header *)http2_buff; if(len < sizeof(Http2_header)){ if(len) LOGD(DHTTP2, "get a incompleted head, size:%zu\n", len); return 0; }else{ uint32_t length = get24(header->length); if(length > FRAMEBODYLIMIT){ LOGE("ERROR frame size: %d\n", length); ErrProc(ERR_FRAME_SIZE_ERROR); return 0; } if(len < length + sizeof(Http2_header)){ LOGD(DHTTP2, "get a incompleted packet, size:%zu/%zu\n", len, length + sizeof(Http2_header)); return 0; }else{ uint32_t id = HTTP2_ID(header->id); if(http2_flag & HTTP2_FLAG_GOAWAYED){ LOG("get a frame [%d]:%d, size:%d after goaway, ignore it.\n", id, header->type, length); return length + sizeof(Http2_header); } LOGD(DHTTP2, "get a frame [%d]:%d, size:%d, flags:%d\n", id, header->type, length, header->flags); try { uint32_t value; switch(header->type) { case DATA_TYPE: if(id == 0 || (id > recvid && id >= sendid-1)){ LOGE("ERROR wrong data id: %d/%d/%d\n", id, recvid, sendid); ErrProc(ERR_PROTOCOL_ERROR); return 0; } DataProc(id, header+1, length); if(header->flags & END_STREAM_F){ EndProc(id); } break; case HEADERS_TYPE: HeadersProc(header); if(header->flags & END_STREAM_F){ EndProc(id); } break; case PRIORITY_TYPE: break; case SETTINGS_TYPE: if(id != 0 || length%6 != 0){ LOGE("ERROR wrong setting frame : %d/%d\n", id, length); ErrProc(ERR_PROTOCOL_ERROR); return 0; } SettingsProc(header); break; case PING_TYPE: if(id != 0 || length != 8){ LOGE("ERROR wrong ping frame: %d/%d\n", id, length); ErrProc(ERR_FRAME_SIZE_ERROR); return 0; } PingProc(header); break; case GOAWAY_TYPE: GoawayProc(header); break; case RST_STREAM_TYPE: value = get32(header+1); if(length != 4){ LOGE("ERROR rst frame: %d/%d\n", id, length); ErrProc(ERR_FRAME_SIZE_ERROR); return 0; } if(id == 0 || (id > recvid && id >= sendid-1)){ LOGE("ERROR rst frame: %d/%d/%d\n", id, sendid, recvid); ErrProc(ERR_PROTOCOL_ERROR); return 0; } RstProc(id, value); break; case WINDOW_UPDATE_TYPE: value = get32(header+1); if(length != 4){ LOGE("ERROR window update frame: %d/%d\n", id, length); ErrProc(ERR_FRAME_SIZE_ERROR); return 0; } if(value == 0 || (id > recvid && id >= sendid-1)){ LOGE("ERROR window update frame: value=%d id=%d/%d/%d\n", value, id, sendid, recvid); ErrProc(ERR_PROTOCOL_ERROR); return 0; } WindowUpdateProc(id, value); break; default: LOGE("unkown http2 frame:%d\n", header->type); } }catch(...){ Reset(id, ERR_INTERNAL_ERROR); return 0; } return length + sizeof(Http2_header); } } }