From f17f51390a1478f1dacbe4381a32ea5c2fcea12e Mon Sep 17 00:00:00 2001 From: Leonid Bugaev Date: Fri, 1 Jul 2016 20:01:25 +0300 Subject: [PATCH] Fix 100-continue with multi-packet headers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also adds —output-null for testing purpose --- Makefile | 4 ++-- output_null.go | 18 ++++++++++++++++++ plugins.go | 4 ++++ raw_socket_listener/listener.go | 19 ++++++++++--------- settings.go | 3 +++ 5 files changed, 37 insertions(+), 11 deletions(-) create mode 100644 output_null.go diff --git a/Makefile b/Makefile index f4b6249..c0c1e45 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -SOURCE = emitter.go gor.go gor_stat.go input_dummy.go input_file.go input_raw.go input_tcp.go limiter.go output_dummy.go output_file.go input_http.go output_http.go output_tcp.go plugins.go settings.go test_input.go elasticsearch.go http_modifier.go http_modifier_settings.go http_client.go middleware.go protocol.go output_file_settings.go +SOURCE = emitter.go gor.go gor_stat.go input_dummy.go input_file.go input_raw.go input_tcp.go limiter.go output_dummy.go output_null.go output_file.go input_http.go output_http.go output_tcp.go plugins.go settings.go test_input.go elasticsearch.go http_modifier.go http_modifier_settings.go http_client.go middleware.go protocol.go output_file_settings.go SOURCE_PATH = /go/src/github.com/buger/gor/ PORT = 8000 FADDR = :8000 @@ -77,7 +77,7 @@ file-server: go run $(SOURCE) file-server $(FADDR) readpcap: - go run $(SOURCE) --input-raw $(FILE) --input-raw-engine pcap_file --output-stdout + go run $(SOURCE) --input-raw $(FILE) --input-raw-engine pcap_file --output-null record: $(RUN) go run $(SOURCE) --input-dummy=0 --output-file=requests.gor --verbose --debug diff --git a/output_null.go b/output_null.go new file mode 100644 index 0000000..14867a2 --- /dev/null +++ b/output_null.go @@ -0,0 +1,18 @@ +package main + +// NullOutput used for debugging, prints nothing +type NullOutput struct { +} + +// NullOutput constructor for NullOutput +func NewNullOutput() (o *NullOutput) { + return new(NullOutput) +} + +func (o *NullOutput) Write(data []byte) (int, error) { + return len(data), nil +} + +func (o *NullOutput) String() string { + return "Null Output" +} diff --git a/plugins.go b/plugins.go index c645d48..1a0f6db 100644 --- a/plugins.go +++ b/plugins.go @@ -95,6 +95,10 @@ func InitPlugins() { registerPlugin(NewDummyOutput) } + if Settings.outputNull { + registerPlugin(NewNullOutput) + } + engine := EnginePcap if Settings.inputRAWEngine == "raw_socket" { engine = EngineRawSocket diff --git a/raw_socket_listener/listener.go b/raw_socket_listener/listener.go index 0cfffa6..f639254 100644 --- a/raw_socket_listener/listener.go +++ b/raw_socket_listener/listener.go @@ -174,14 +174,8 @@ func (t *Listener) dispatchMessage(message *TCPMessage) { return } - log.Println("MESSAGE:", message, message.BodySize(), message.contentLength, message.methodType, message.bodyType) - t.deleteMessage(message) - if message.methodType == httpMethodNotFound { - return - } - if !message.complete { if !message.IsIncoming { delete(t.respAliases, message.Ack) @@ -494,7 +488,6 @@ func (t *Listener) readPcapFile() { data = append(tcp.LayerContents(), tcp.LayerPayload()...) copy(data[2:4], []byte{0, 1}) } else { - log.Println("Can't find TCP layer", packet) continue } @@ -505,7 +498,15 @@ func (t *Listener) readPcapFile() { ip, _ := ipLayer.(*layers.IPv6) addr = ip.SrcIP } else { - log.Println("Can't find IP layer", packet) + // log.Println("Can't find IP layer", packet) + continue + } + + dataOffset := (data[12] & 0xF0) >> 4 + + // We need only packets with data inside + // Check that the buffer is larger than the size of the TCP header + if len(data) <= int(dataOffset*4) { continue } @@ -650,7 +651,7 @@ func (t *Listener) processTCPPacket(packet *TCPPacket) { // Handling Expect: 100-continue requests if message.expectType == httpExpect100Continue && len(message.packets) == message.headerPacket+1 { - seq := packet.Seq + uint32(len(packet.Data)) + seq := packet.Seq + uint32(message.Size()) t.seqWithData[seq] = packet.Ack message.DataSeq = seq message.complete = false diff --git a/settings.go b/settings.go index 702dcfc..dd0675c 100644 --- a/settings.go +++ b/settings.go @@ -34,6 +34,7 @@ type AppSettings struct { inputDummy MultiOption outputDummy MultiOption outputStdout bool + outputNull bool inputTCP MultiOption outputTCP MultiOption @@ -81,6 +82,8 @@ func init() { flag.BoolVar(&Settings.outputStdout, "output-stdout", false, "Used for testing inputs. Just prints to console data coming from inputs.") + flag.BoolVar(&Settings.outputNull, "output-null", false, "Used for testing inputs. Drops all requests.") + flag.Var(&Settings.inputTCP, "input-tcp", "Used for internal communication between Gor instances. Example: \n\t# Receive requests from other Gor instances on 28020 port, and redirect output to staging\n\tgor --input-tcp :28020 --output-http staging.com") flag.Var(&Settings.outputTCP, "output-tcp", "Used for internal communication between Gor instances. Example: \n\t# Listen for requests on 80 port and forward them to other Gor instance on 28020 port\n\tgor --input-raw :80 --output-tcp replay.local:28020") flag.BoolVar(&Settings.outputTCPStats, "output-tcp-stats", false, "Report TCP output queue stats to console every 5 seconds.")