Commit Graph
34 Commits
Author SHA1 Message Date
Leonid Bugaev bb1bca6f3c Missing messages fixes (#1007)
This PR contains multiple fixes:
- Handle TCP padding (zeroes at the end of TCP payload), and do not treat it as a body
- Handle requests with "Expect: 100-Continue" - the ones which require confirmation from the server, before sending the body
- Fix muti-packet headers parsing, if "truncated" header starts with malformed header format
- Fix replay of pcap files (Ignore Stats method since it is not supported)
- Fix output file chunk size detection
2021-08-30 20:22:21 +03:00
Leonid BugaevandGitHub fe25ddd0fb Merge pull request #982 from DimaGolomozy/testing-fix-work
Testing fix work
2021-08-16 20:07:31 +03:00
dimagolomozy f4895e00d5 no Src and Dst addr in message 2021-08-16 19:05:57 +03:00
Leonid Bugaev 11d61dcb4d Make packet proccessing multi threaded
If packet processign is not fast enough, packet capture may miss packets
Now it use 10 goroutines, which distribute work based on the ephemeral port number
2021-08-06 21:24:18 +03:00
dimagolomozy f11d59ba19 fix sleep time 2021-08-03 15:21:46 +03:00
Leonid Bugaev 214edb45f6 Optimise packet capture thread
Ensure that thread which capture packets as fast as possible.
Packet parsing logic moved to different threads.
Additionally using os.LockOsThread to reduce CPU context switching
2021-07-26 21:01:59 +03:00
Leonid Bugaev c01be50d72 Fix issue with multi-packet messages and fix tests 2021-07-19 20:36:12 +03:00
Leonid Bugaev df2b4be898 Fix detection of packet detection for complex bpf fiters
Right now it depends on the defined ports, but you can have more compex bpf, so wee may stil need ti check it with Start function
2021-07-16 22:18:28 +03:00
Leonid Bugaev 0902a10c2d Rollback to use non ZeroCopy methods, and remove poling 2021-07-13 23:37:39 +03:00
Leonid Bugaev 710cbe10e3 Simplify packet pooling and improve copySlice
Pooling now use just sync.Pool, copySlice using trick from gopacket library
2021-07-12 23:24:22 +03:00
Leonid Bugaev 61b377d123 Do not use buffer pool for messages
This buffers are get re-used and data gets corrupted
2021-07-08 23:00:12 +03:00
Leonid Bugaev 8edb74e572 Add support for "go" timestamp source
Windows having issues with generating timestamps, so adding application level timestamp generation
Made small refactoring to move "accurate-enough" time to own package.
2021-07-07 20:56:22 +03:00
Leonid Bugaev 5d718e92ea Add exvar to expose debug variables 2021-07-07 12:30:13 +03:00
Leonid Bugaev 148846be93 GC optimisations 2021-07-07 03:04:28 +03:00
Leonid Bugaev 0bb72e0f60 Add buffer pooling for message data 2021-07-07 02:58:00 +03:00
Leonid Bugaev 724c0890c9 Improve memory allocations
A lot of improvements, and own GC for packet pool
2021-07-07 02:08:23 +03:00
Leonid BugaevandGitHub 9468978353 Skip not complete HTTP messages (#953)
Added `--input-raw-allow-incomplete` if you really need it.

Fixed Bug when outpuut binary response not tracked
Additionally fixed bug which prevents Gor from exiting.
2021-06-28 23:01:58 +03:00
Leonid Bugaev db32671c52 Memory utilization improvements
Do not use sync.Pool, use channel based impementation instead. Sync pool does not work for long lived objects, and trigger frequent GC.
Because of MUCH more efficient memory utilization, GOGC now set to 500, which significantly improve CPU as wel.
2021-06-27 21:05:10 +00:00
Leonid Bugaev 4b864199cd Add ZeroCopy back and fix ring packet processing
The cause was not ZeroCopy but wrong SetTimeout (block cause a lot of overhead).

Packet processing previously used channels, but now, with ring buffer, using select was causing issue. Adding `default` clause fixed the issue.
2021-06-27 19:17:06 +00:00
Leonid Bugaev 67154f6a62 Replace channels with Ring Buffer
Channes cause a lot of locking, and Ring Buffer data structure shows way better performance in our case
2021-06-27 17:18:57 +00:00
Leonid Bugaev bbefdf5710 Fix tests
They were duplicated in tcp package
2021-06-26 15:05:29 +00:00
Leonid BugaevandGitHub 58ff8865df Fix windows packet capture (#943)
Issues is that Go built-in net.Interfaces function in newer Windows versions return wrong interface names, which libpcap can't consume.
Now we use pcap.FindDevices instead of net.Interfaces.
See this Article for deep understanding of the issue https://haydz.github.io/2020/07/06/Go-Windows-NIC.html

Additionally, found a bug causing big memory allocations, for large requests, when we perform check if messages finished or not.
Because of this bug chunked body encoding check was not working properly.
Was not caught in tests, because test was working on packet array level, and this issue happens when dealing with TCP message object.

Additionally, added a small fix for windows Makefile task, it now generates proper file name.
2021-06-10 14:46:17 +03:00
Vincent ComposieuxandGitHub 1e8c879bc6 Fixed unusued "fmt" error in tcp_message.go (#933) 2021-05-21 21:40:11 +03:00
Urban IshimweandGitHub e74e945e7f Fixing performance issues and out-of-order packets (#916)
### Reducing CPU context switching and number of goroutines. 
Packet capture and packet processing now use only two goroutines which helps to minimize CPU context switches. Spawning too many goroutines is harmful here. 

### Optimized packet capture - allocated memory only when required, and only for data which is used
Using ZeroCopy methods from libpcap library to avoid unnecessary allocations. Now memory gets allocated ONLY for the valid packets, and only for the packets which have the data. E.g. no SYN/FIN packets are used now. Additionally we now use `sync.Pool` for re-using packet objects, which helps to re-use already allocated memory. 

### Simplification and optimization of request/response detection
There is no SYN/FIN packets anymore etc. Now only packet payload is used to detect start and end of the packet. More over payload detection now does not require generating a total “message” buffer, and works with individual packet payloads. 

Message payloads now concatenated from packets only in the end when message is dispatched. Also, before checking if message is complete, added additional check if all received packets in the valid order, e.g. if their SEQ is valid, and no packets are missing. 

Reworked chunked encoding validation, and now it does not need expensive operation of re-calculating all the chunks. Now it “trust” that client gives valid chunk body, check if packets are in the right order (e.g. SEQ match), and checks if message ends with the right suffix. All is done with 0 allocations. 

Parsing all Headers using `proto.GetHeaders` was proved to be very slow. Now we only parse the headers we need(and do it only once).

Packets gets matched together using ACK, which on high RPS removed chances of duplicating IDs. Additionally, even if packets are received out of order, now it will properly sort them, before dispatching the message.

### Changes in ID generation algorithm
Message ID generation and relations between request and response IDs is fully rewritten. Responses now do not have to lookup for request data in order to get the same ID. ID no rely on the fact that SEQ of the first packet of the response should be the same as ACK of the request. If previously Message ID contained random values, like current timestamp, now it has a consistent algorithm which is based on TCP stream id (SrcPort + DstPort + SrcIP/DstIP) and current ACK/SEQ number (to distinguish multiple messages within the same stream).

### BPF filter optimizations
When tracking response it now uses a more accurate BPF rule to filter only needed traffic. 

### Misc
The packet code is now fully moved to tcp/Packet, so packet processing done only once in one place.

TCP output now has a 5 second timeout, and has a proper Close method.

Fully switching to go modules and removing vendoring.
2021-05-19 20:11:25 +03:00
Urban IshimweandGitHub a526f3a5f1 lazy packet parser (#870)
benchmarks of packet parser with `-cpu=1` packet (IPv6 with 2 extension header)
master:
```
337463	      3300 ns/op	    1624 B/op	      24 allocs/op
```
current:
```
2014885       576 ns/op	            384 B/op	       3 allocs/op
```
2020-12-21 19:41:21 +03:00
Urban IshimweandGitHub f6a4170615 refine HTTP1 end hint (#863)
fixes #859
2020-12-04 11:27:02 +03:00
Urban IshimweandGitHub a84898ce8b remove unsafe converison (#865) 2020-12-04 11:26:37 +03:00
Urban IshimweandGitHub 5e2bbf8228 tcp.message uuid fix (#855)
the current UUID generator runs at:
```
BenchmarkMessageUUID 	13599342	        87.7 ns/op	      16 B/op	       0 allocs/op
```
 with the former version that was running on
```
BenchmarkMessageUUID 	 2818203	       427 ns/op	      96 B/op	       2 allocs/op
```

it fixes #842 #851
2020-11-16 15:01:06 +03:00
Urban IshimweandGitHub 9519b9a9f5 Reduce allocation and unnecessary layers (#822)
The focus here was to **reduce allocation in TCP parser** but speed may have hopeful improved too!
pool no longer use map's key of **string** it uses **uint64**
**Benchmarks** was revamped to be more clear
if you want to compare these results copy the benchmark in tcp/bench_test.go@reduce-allocation to tcp/bench_test.go@master:

**before(master)**:
```
BenchmarkPacketParseAndSort-4         	 1000000	      1006 ns/op	      64 B/op	       2 allocs/op
BenchmarkMessageParserWithoutHint-4   	     625	   1772309 ns/op	      1000 packets/op	  419096 B/op	   10045 allocs/op
BenchmarkMessageParserWithHint-4      	      74	  14969926 ns/op	      1000 chunks/op	      1002 packets/op	  450992 B/op	   10126 allocs/op
```

**After(this branch)**:
```
BenchmarkPacketParseAndSort-4         	 1267662	       941 ns/op	      64 B/op	       2 allocs/op
BenchmarkMessageParserWithoutHint-4   	    2256	    523474 ns/op	      1000 packets/op	  243530 B/op	    1037 allocs/op
BenchmarkMessageParserWithHint-4      	      80	  13990955 ns/op	      1000 chunks/op	      1002 packets/op	  268609 B/op	    1099 allocs/op

```
2020-09-22 21:14:31 +03:00
Urban Ishimwe 48150e53ba make syn work with hint 2020-08-30 12:16:24 +02:00
Urban Ishimwe f9b0ae6d55 fix #809 and minor bug in pool 2020-08-30 12:07:00 +02:00
Urban Ishimwe 571487b135 dispatch on rst flag 2020-08-26 17:48:17 +02:00
Urban Ishimwe a03eb92c1e implements af_packet socket 2020-08-23 22:42:18 +02:00
Urban IshimweandGitHub fdc8b094f0 Benchmarking, packaging, and fix issues, tests and perfomance (#797)
### performance
- handling of the very big packet(any size that can be buffered)
- speeding up TCP sessions by using message hints: Added **proto.HasFullPayload** that helps to validate the entire HTTP request, it supports `Chunked` encoding too! Added **proto.HasRequestTitle** and **proto.HasResponseTitle** for validating the beginning of HTTP request. Those methods are used `input_raw.go` with `TCP`.
- supports Keep-Alive: the above functions helps to support keep-alive

### Packaging
- **capture:** engines(capture/doc.go)
- **tcp:** tcp message parser (tcp/doc.go)

### benchmarking
- **capture.BenchmarkPcapDump:** the benchmarks regarding dumping packets in a pcap file
- **capture.BenchmarkPcapFile:** the benchmarks of reading packets from a pcap file
- **capture.BenchmarkPcap:** the benchmarks of parsing packets from the loopback interface with pcap handles
- **proto.BenchmarkHasFullPayload:**: benchmarking this function which validates the HTTP payload
- **tcp.BenchmarkPacketParseAndSort:** benchmarks of parsing and sorting packets
- **tcp.BenchmarkMessageParserWithoutHint:** benchmarks of message reasembling by using `SYN` and `FIN` flag
- **tcp.BenchmarkMessageParserWithHint:** benchmarks of message reasembling by using `proto.HasRequestTitle` and `proto.HasFullPayload` flag

### issues
see linked issues

###  tests
- fixed input raw and engine tests

**Most of the changed of the files, was about using functionalities of** `tcp` **and** `capture` **in existing functionalities**
2020-08-11 12:44:53 +03:00