mirror of
https://github.com/kubeshark/kubeshark.git
synced 2026-02-26 00:24:17 +00:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d5b01347df | ||
|
|
7dca1ad889 | ||
|
|
616eccb2cf | ||
|
|
30f07479cb | ||
|
|
7f880417e9 | ||
|
|
6b52458642 |
76
.github/CODE_OF_CONDUCT.md
vendored
Normal file
76
.github/CODE_OF_CONDUCT.md
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as
|
||||
contributors and maintainers pledge to making participation in our project and
|
||||
our community a harassment-free experience for everyone, regardless of age, body
|
||||
size, disability, ethnicity, sex characteristics, gender identity and expression,
|
||||
level of experience, education, socio-economic status, nationality, personal
|
||||
appearance, race, religion, or sexual identity and orientation.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment
|
||||
include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or
|
||||
advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic
|
||||
address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Our Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of acceptable
|
||||
behavior and are expected to take appropriate and fair corrective action in
|
||||
response to any instances of unacceptable behavior.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or
|
||||
reject comments, commits, code, wiki edits, issues, and other contributions
|
||||
that are not aligned to this Code of Conduct, or to ban temporarily or
|
||||
permanently any contributor for other behaviors that they deem inappropriate,
|
||||
threatening, offensive, or harmful.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies both within project spaces and in public spaces
|
||||
when an individual is representing the project or its community. Examples of
|
||||
representing a project or community include using an official project e-mail
|
||||
address, posting via an official social media account, or acting as an appointed
|
||||
representative at an online or offline event. Representation of a project may be
|
||||
further defined and clarified by project maintainers.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported by contacting the project team at mizu@up9.com. All
|
||||
complaints will be reviewed and investigated and will result in a response that
|
||||
is deemed necessary and appropriate to the circumstances. The project team is
|
||||
obligated to maintain confidentiality with regard to the reporter of an incident.
|
||||
Further details of specific enforcement policies may be posted separately.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good
|
||||
faith may face temporary or permanent repercussions as determined by other
|
||||
members of the project's leadership.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
||||
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
|
||||
|
||||
[homepage]: https://www.contributor-covenant.org
|
||||
|
||||
For answers to common questions about this code of conduct, see
|
||||
https://www.contributor-covenant.org/faq
|
||||
16
CONTRIBUTE.md → .github/CONTRIBUTING.md
vendored
16
CONTRIBUTE.md → .github/CONTRIBUTING.md
vendored
@@ -1,18 +1,20 @@
|
||||

|
||||
# CONTRIBUTE
|
||||
|
||||
# Contributing to Mizu
|
||||
|
||||
We welcome code contributions from the community.
|
||||
Please read and follow the guidelines below.
|
||||
|
||||
## Communication
|
||||
|
||||
* Before starting work on a major feature, please reach out to us via [GitHub](https://github.com/up9inc/mizu), [Slack](https://join.slack.com/share/zt-u6bbs3pg-X1zhQOXOH0yEoqILgH~csw), [email](mailto:mizu@up9.com), etc. We will make sure no one else is already working on it. A _major feature_ is defined as any change that is > 100 LOC altered (not including tests), or changes any user-facing behavior
|
||||
* Small patches and bug fixes don't need prior communication.
|
||||
|
||||
## Contribution requirements
|
||||
## Contribution Requirements
|
||||
|
||||
* Code style - most of the code is written in Go, please follow [these guidelines](https://golang.org/doc/effective_go)
|
||||
* Go-tools compatible (`go get`, `go test`, etc)
|
||||
* Unit-test coverage can’t go down ..
|
||||
* Go-tools compatible (`go get`, `go test`, etc.)
|
||||
* Code coverage for unit tests must not decrease.
|
||||
* Code must be usefully commented. Not only for developers on the project, but also for external users of these packages
|
||||
* When reviewing PRs, you are encouraged to use Golang's [code review comments page](https://github.com/golang/go/wiki/CodeReviewComments)
|
||||
|
||||
|
||||
|
||||
* Project follows [Google JSON Style Guide](https://google.github.io/styleguide/jsoncstyleguide.xml) for the REST APIs that are provided.
|
||||
@@ -3,7 +3,6 @@ package cmd
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"os/signal"
|
||||
@@ -63,8 +62,8 @@ func openBrowser(url string) {
|
||||
default:
|
||||
err = fmt.Errorf("unsupported platform")
|
||||
}
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
logger.Log.Errorf("error while opening browser, %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -379,13 +379,28 @@ func watchPodsForTapping(ctx context.Context, kubernetesProvider *kubernetes.Pro
|
||||
|
||||
for {
|
||||
select {
|
||||
case pod := <-added:
|
||||
case pod, ok := <-added:
|
||||
if !ok {
|
||||
added = nil
|
||||
continue
|
||||
}
|
||||
|
||||
logger.Log.Debugf("Added matching pod %s, ns: %s", pod.Name, pod.Namespace)
|
||||
restartTappersDebouncer.SetOn()
|
||||
case pod := <-removed:
|
||||
case pod, ok := <-removed:
|
||||
if !ok {
|
||||
removed = nil
|
||||
continue
|
||||
}
|
||||
|
||||
logger.Log.Debugf("Removed matching pod %s, ns: %s", pod.Name, pod.Namespace)
|
||||
restartTappersDebouncer.SetOn()
|
||||
case pod := <-modified:
|
||||
case pod, ok := <-modified:
|
||||
if !ok {
|
||||
modified = nil
|
||||
continue
|
||||
}
|
||||
|
||||
logger.Log.Debugf("Modified matching pod %s, ns: %s, phase: %s, ip: %s", pod.Name, pod.Namespace, pod.Status.Phase, pod.Status.PodIP)
|
||||
// Act only if the modified pod has already obtained an IP address.
|
||||
// After filtering for IPs, on a normal pod restart this includes the following events:
|
||||
@@ -396,8 +411,12 @@ func watchPodsForTapping(ctx context.Context, kubernetesProvider *kubernetes.Pro
|
||||
if pod.Status.PodIP != "" {
|
||||
restartTappersDebouncer.SetOn()
|
||||
}
|
||||
case err, ok := <-errorChan:
|
||||
if !ok {
|
||||
errorChan = nil
|
||||
continue
|
||||
}
|
||||
|
||||
case err := <-errorChan:
|
||||
logger.Log.Debugf("Watching pods loop, got error %v, stopping `restart tappers debouncer`", err)
|
||||
restartTappersDebouncer.Cancel()
|
||||
// TODO: Does this also perform cleanup?
|
||||
@@ -477,21 +496,28 @@ func watchApiServerPod(ctx context.Context, kubernetesProvider *kubernetes.Provi
|
||||
timeAfter := time.After(25 * time.Second)
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
logger.Log.Debugf("Watching API Server pod loop, ctx done")
|
||||
return
|
||||
case <-added:
|
||||
case _, ok := <-added:
|
||||
if !ok {
|
||||
added = nil
|
||||
continue
|
||||
}
|
||||
|
||||
logger.Log.Debugf("Watching API Server pod loop, added")
|
||||
continue
|
||||
case <-removed:
|
||||
case _, ok := <-removed:
|
||||
if !ok {
|
||||
removed = nil
|
||||
continue
|
||||
}
|
||||
|
||||
logger.Log.Infof("%s removed", mizu.ApiServerPodName)
|
||||
cancel()
|
||||
return
|
||||
case modifiedPod := <-modified:
|
||||
if modifiedPod == nil {
|
||||
logger.Log.Debugf("Watching API Server pod loop, modifiedPod with nil")
|
||||
case modifiedPod, ok := <-modified:
|
||||
if !ok {
|
||||
modified = nil
|
||||
continue
|
||||
}
|
||||
|
||||
logger.Log.Debugf("Watching API Server pod loop, modified: %v", modifiedPod.Status.Phase)
|
||||
if modifiedPod.Status.Phase == core.PodRunning && !isPodReady {
|
||||
isPodReady = true
|
||||
@@ -510,14 +536,23 @@ func watchApiServerPod(ctx context.Context, kubernetesProvider *kubernetes.Provi
|
||||
logger.Log.Debugf("[Error] failed update tapped pods %v", err)
|
||||
}
|
||||
}
|
||||
case _, ok := <-errorChan:
|
||||
if !ok {
|
||||
errorChan = nil
|
||||
continue
|
||||
}
|
||||
|
||||
logger.Log.Debugf("[ERROR] Agent creation, watching %v namespace", config.Config.MizuResourcesNamespace)
|
||||
cancel()
|
||||
|
||||
case <-timeAfter:
|
||||
if !isPodReady {
|
||||
logger.Log.Errorf(uiUtils.Error, "Mizu API server was not ready in time")
|
||||
cancel()
|
||||
}
|
||||
case <-errorChan:
|
||||
logger.Log.Debugf("[ERROR] Agent creation, watching %v namespace", config.Config.MizuResourcesNamespace)
|
||||
cancel()
|
||||
case <-ctx.Done():
|
||||
logger.Log.Debugf("Watching API Server pod loop, ctx done")
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,13 +9,13 @@ import (
|
||||
|
||||
type Protocol struct {
|
||||
Name string `json:"name"`
|
||||
LongName string `json:"long_name"`
|
||||
LongName string `json:"longName"`
|
||||
Abbreviation string `json:"abbreviation"`
|
||||
Version string `json:"version"`
|
||||
BackgroundColor string `json:"background_color"`
|
||||
ForegroundColor string `json:"foreground_color"`
|
||||
FontSize int8 `json:"font_size"`
|
||||
ReferenceLink string `json:"reference_link"`
|
||||
BackgroundColor string `json:"backgroundColor"`
|
||||
ForegroundColor string `json:"foregroundColor"`
|
||||
FontSize int8 `json:"fontSize"`
|
||||
ReferenceLink string `json:"referenceLink"`
|
||||
Ports []string `json:"ports"`
|
||||
Priority uint8 `json:"priority"`
|
||||
}
|
||||
@@ -50,8 +50,8 @@ type CounterPair struct {
|
||||
}
|
||||
|
||||
type GenericMessage struct {
|
||||
IsRequest bool `json:"is_request"`
|
||||
CaptureTime time.Time `json:"capture_time"`
|
||||
IsRequest bool `json:"isRequest"`
|
||||
CaptureTime time.Time `json:"captureTime"`
|
||||
Payload interface{} `json:"payload"`
|
||||
}
|
||||
|
||||
@@ -87,6 +87,7 @@ type Dissector interface {
|
||||
}
|
||||
|
||||
type Emitting struct {
|
||||
AppStats *AppStats
|
||||
OutputChannel chan *OutputChannelItem
|
||||
}
|
||||
|
||||
@@ -96,32 +97,39 @@ type Emitter interface {
|
||||
|
||||
func (e *Emitting) Emit(item *OutputChannelItem) {
|
||||
e.OutputChannel <- item
|
||||
e.AppStats.IncMatchedPairs()
|
||||
}
|
||||
|
||||
type MizuEntry struct {
|
||||
ID uint `gorm:"primarykey"`
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
ProtocolName string `json:"protocol_key" gorm:"column:protocolKey"`
|
||||
ProtocolVersion string `json:"protocol_version" gorm:"column:protocolVersion"`
|
||||
Entry string `json:"entry,omitempty" gorm:"column:entry"`
|
||||
EntryId string `json:"entryId" gorm:"column:entryId"`
|
||||
Url string `json:"url" gorm:"column:url"`
|
||||
Method string `json:"method" gorm:"column:method"`
|
||||
Status int `json:"status" gorm:"column:status"`
|
||||
RequestSenderIp string `json:"requestSenderIp" gorm:"column:requestSenderIp"`
|
||||
Service string `json:"service" gorm:"column:service"`
|
||||
Timestamp int64 `json:"timestamp" gorm:"column:timestamp"`
|
||||
ElapsedTime int64 `json:"elapsedTime" gorm:"column:elapsedTime"`
|
||||
Path string `json:"path" gorm:"column:path"`
|
||||
ResolvedSource string `json:"resolvedSource,omitempty" gorm:"column:resolvedSource"`
|
||||
ResolvedDestination string `json:"resolvedDestination,omitempty" gorm:"column:resolvedDestination"`
|
||||
SourceIp string `json:"sourceIp,omitempty" gorm:"column:sourceIp"`
|
||||
DestinationIp string `json:"destinationIp,omitempty" gorm:"column:destinationIp"`
|
||||
SourcePort string `json:"sourcePort,omitempty" gorm:"column:sourcePort"`
|
||||
DestinationPort string `json:"destinationPort,omitempty" gorm:"column:destinationPort"`
|
||||
IsOutgoing bool `json:"isOutgoing,omitempty" gorm:"column:isOutgoing"`
|
||||
EstimatedSizeBytes int `json:"-" gorm:"column:estimatedSizeBytes"`
|
||||
ID uint `gorm:"primarykey"`
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
ProtocolName string `json:"protocolName" gorm:"column:protocolName"`
|
||||
ProtocolLongName string `json:"protocolLongName" gorm:"column:protocolLongName"`
|
||||
ProtocolAbbreviation string `json:"protocolAbbreviation" gorm:"column:protocolVersion"`
|
||||
ProtocolVersion string `json:"protocolVersion" gorm:"column:protocolVersion"`
|
||||
ProtocolBackgroundColor string `json:"protocolBackgroundColor" gorm:"column:protocolBackgroundColor"`
|
||||
ProtocolForegroundColor string `json:"protocolForegroundColor" gorm:"column:protocolForegroundColor"`
|
||||
ProtocolFontSize int8 `json:"protocolFontSize" gorm:"column:protocolFontSize"`
|
||||
ProtocolReferenceLink string `json:"protocolReferenceLink" gorm:"column:protocolReferenceLink"`
|
||||
Entry string `json:"entry,omitempty" gorm:"column:entry"`
|
||||
EntryId string `json:"entryId" gorm:"column:entryId"`
|
||||
Url string `json:"url" gorm:"column:url"`
|
||||
Method string `json:"method" gorm:"column:method"`
|
||||
Status int `json:"status" gorm:"column:status"`
|
||||
RequestSenderIp string `json:"requestSenderIp" gorm:"column:requestSenderIp"`
|
||||
Service string `json:"service" gorm:"column:service"`
|
||||
Timestamp int64 `json:"timestamp" gorm:"column:timestamp"`
|
||||
ElapsedTime int64 `json:"elapsedTime" gorm:"column:elapsedTime"`
|
||||
Path string `json:"path" gorm:"column:path"`
|
||||
ResolvedSource string `json:"resolvedSource,omitempty" gorm:"column:resolvedSource"`
|
||||
ResolvedDestination string `json:"resolvedDestination,omitempty" gorm:"column:resolvedDestination"`
|
||||
SourceIp string `json:"sourceIp,omitempty" gorm:"column:sourceIp"`
|
||||
DestinationIp string `json:"destinationIp,omitempty" gorm:"column:destinationIp"`
|
||||
SourcePort string `json:"sourcePort,omitempty" gorm:"column:sourcePort"`
|
||||
DestinationPort string `json:"destinationPort,omitempty" gorm:"column:destinationPort"`
|
||||
IsOutgoing bool `json:"isOutgoing,omitempty" gorm:"column:isOutgoing"`
|
||||
EstimatedSizeBytes int `json:"-" gorm:"column:estimatedSizeBytes"`
|
||||
}
|
||||
|
||||
type MizuEntryWrapper struct {
|
||||
@@ -135,17 +143,17 @@ type BaseEntryDetails struct {
|
||||
Id string `json:"id,omitempty"`
|
||||
Protocol Protocol `json:"protocol,omitempty"`
|
||||
Url string `json:"url,omitempty"`
|
||||
RequestSenderIp string `json:"request_sender_ip,omitempty"`
|
||||
RequestSenderIp string `json:"requestSenderIp,omitempty"`
|
||||
Service string `json:"service,omitempty"`
|
||||
Path string `json:"path,omitempty"`
|
||||
Summary string `json:"summary,omitempty"`
|
||||
StatusCode int `json:"status_code"`
|
||||
StatusCode int `json:"statusCode"`
|
||||
Method string `json:"method,omitempty"`
|
||||
Timestamp int64 `json:"timestamp,omitempty"`
|
||||
SourceIp string `json:"source_ip,omitempty"`
|
||||
DestinationIp string `json:"destination_ip,omitempty"`
|
||||
SourcePort string `json:"source_port,omitempty"`
|
||||
DestinationPort string `json:"destination_port,omitempty"`
|
||||
SourceIp string `json:"sourceIp,omitempty"`
|
||||
DestinationIp string `json:"destinationIp,omitempty"`
|
||||
SourcePort string `json:"sourcePort,omitempty"`
|
||||
DestinationPort string `json:"destinationPort,omitempty"`
|
||||
IsOutgoing bool `json:"isOutgoing,omitempty"`
|
||||
Latency int64 `json:"latency,omitempty"`
|
||||
Rules ApplicableRules `json:"rules,omitempty"`
|
||||
@@ -162,11 +170,19 @@ type DataUnmarshaler interface {
|
||||
}
|
||||
|
||||
func (bed *BaseEntryDetails) UnmarshalData(entry *MizuEntry) error {
|
||||
entryUrl := entry.Url
|
||||
service := entry.Service
|
||||
bed.Protocol = Protocol{
|
||||
Name: entry.ProtocolName,
|
||||
LongName: entry.ProtocolLongName,
|
||||
Abbreviation: entry.ProtocolAbbreviation,
|
||||
Version: entry.ProtocolVersion,
|
||||
BackgroundColor: entry.ProtocolBackgroundColor,
|
||||
ForegroundColor: entry.ProtocolForegroundColor,
|
||||
FontSize: entry.ProtocolFontSize,
|
||||
ReferenceLink: entry.ProtocolReferenceLink,
|
||||
}
|
||||
bed.Id = entry.EntryId
|
||||
bed.Url = entryUrl
|
||||
bed.Service = service
|
||||
bed.Url = entry.Url
|
||||
bed.Service = entry.Service
|
||||
bed.Summary = entry.Path
|
||||
bed.StatusCode = entry.Status
|
||||
bed.Method = entry.Method
|
||||
|
||||
70
tap/api/stats_tracker.go
Normal file
70
tap/api/stats_tracker.go
Normal file
@@ -0,0 +1,70 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"sync/atomic"
|
||||
"time"
|
||||
)
|
||||
|
||||
type AppStats struct {
|
||||
StartTime time.Time `json:"-"`
|
||||
ProcessedBytes uint64 `json:"processedBytes"`
|
||||
PacketsCount uint64 `json:"packetsCount"`
|
||||
TcpPacketsCount uint64 `json:"tcpPacketsCount"`
|
||||
ReassembledTcpPayloadsCount uint64 `json:"reassembledTcpPayloadsCount"`
|
||||
TlsConnectionsCount uint64 `json:"tlsConnectionsCount"`
|
||||
MatchedPairs uint64 `json:"matchedPairs"`
|
||||
DroppedTcpStreams uint64 `json:"droppedTcpStreams"`
|
||||
}
|
||||
|
||||
func (as *AppStats) IncMatchedPairs() {
|
||||
atomic.AddUint64(&as.MatchedPairs, 1)
|
||||
}
|
||||
|
||||
func (as *AppStats) IncDroppedTcpStreams() {
|
||||
atomic.AddUint64(&as.DroppedTcpStreams, 1)
|
||||
}
|
||||
|
||||
func (as *AppStats) IncPacketsCount() uint64 {
|
||||
atomic.AddUint64(&as.PacketsCount, 1)
|
||||
return as.PacketsCount
|
||||
}
|
||||
|
||||
func (as *AppStats) IncTcpPacketsCount() {
|
||||
atomic.AddUint64(&as.TcpPacketsCount, 1)
|
||||
}
|
||||
|
||||
func (as *AppStats) IncReassembledTcpPayloadsCount() {
|
||||
atomic.AddUint64(&as.ReassembledTcpPayloadsCount, 1)
|
||||
}
|
||||
|
||||
func (as *AppStats) IncTlsConnectionsCount() {
|
||||
atomic.AddUint64(&as.TlsConnectionsCount, 1)
|
||||
}
|
||||
|
||||
func (as *AppStats) UpdateProcessedBytes(size uint64) {
|
||||
atomic.AddUint64(&as.ProcessedBytes, size)
|
||||
}
|
||||
|
||||
func (as *AppStats) SetStartTime(startTime time.Time) {
|
||||
as.StartTime = startTime
|
||||
}
|
||||
|
||||
func (as *AppStats) DumpStats() *AppStats {
|
||||
currentAppStats := &AppStats{StartTime: as.StartTime}
|
||||
|
||||
currentAppStats.ProcessedBytes = resetUint64(&as.ProcessedBytes)
|
||||
currentAppStats.PacketsCount = resetUint64(&as.PacketsCount)
|
||||
currentAppStats.TcpPacketsCount = resetUint64(&as.TcpPacketsCount)
|
||||
currentAppStats.ReassembledTcpPayloadsCount = resetUint64(&as.ReassembledTcpPayloadsCount)
|
||||
currentAppStats.TlsConnectionsCount = resetUint64(&as.TlsConnectionsCount)
|
||||
currentAppStats.MatchedPairs = resetUint64(&as.MatchedPairs)
|
||||
currentAppStats.DroppedTcpStreams = resetUint64(&as.DroppedTcpStreams)
|
||||
|
||||
return currentAppStats
|
||||
}
|
||||
|
||||
func resetUint64(ref *uint64) (val uint64) {
|
||||
val = atomic.LoadUint64(ref)
|
||||
atomic.StoreUint64(ref, 0)
|
||||
return
|
||||
}
|
||||
@@ -267,25 +267,31 @@ func (d dissecting) Analyze(item *api.OutputChannelItem, entryId string, resolve
|
||||
request["url"] = summary
|
||||
entryBytes, _ := json.Marshal(item.Pair)
|
||||
return &api.MizuEntry{
|
||||
ProtocolName: protocol.Name,
|
||||
ProtocolVersion: protocol.Version,
|
||||
EntryId: entryId,
|
||||
Entry: string(entryBytes),
|
||||
Url: fmt.Sprintf("%s%s", service, summary),
|
||||
Method: request["method"].(string),
|
||||
Status: 0,
|
||||
RequestSenderIp: item.ConnectionInfo.ClientIP,
|
||||
Service: service,
|
||||
Timestamp: item.Timestamp,
|
||||
ElapsedTime: 0,
|
||||
Path: summary,
|
||||
ResolvedSource: resolvedSource,
|
||||
ResolvedDestination: resolvedDestination,
|
||||
SourceIp: item.ConnectionInfo.ClientIP,
|
||||
DestinationIp: item.ConnectionInfo.ServerIP,
|
||||
SourcePort: item.ConnectionInfo.ClientPort,
|
||||
DestinationPort: item.ConnectionInfo.ServerPort,
|
||||
IsOutgoing: item.ConnectionInfo.IsOutgoing,
|
||||
ProtocolName: protocol.Name,
|
||||
ProtocolLongName: protocol.LongName,
|
||||
ProtocolAbbreviation: protocol.Abbreviation,
|
||||
ProtocolVersion: protocol.Version,
|
||||
ProtocolBackgroundColor: protocol.BackgroundColor,
|
||||
ProtocolForegroundColor: protocol.ForegroundColor,
|
||||
ProtocolFontSize: protocol.FontSize,
|
||||
ProtocolReferenceLink: protocol.ReferenceLink,
|
||||
EntryId: entryId,
|
||||
Entry: string(entryBytes),
|
||||
Url: fmt.Sprintf("%s%s", service, summary),
|
||||
Method: request["method"].(string),
|
||||
Status: 0,
|
||||
RequestSenderIp: item.ConnectionInfo.ClientIP,
|
||||
Service: service,
|
||||
Timestamp: item.Timestamp,
|
||||
ElapsedTime: 0,
|
||||
Path: summary,
|
||||
ResolvedSource: resolvedSource,
|
||||
ResolvedDestination: resolvedDestination,
|
||||
SourceIp: item.ConnectionInfo.ClientIP,
|
||||
DestinationIp: item.ConnectionInfo.ServerIP,
|
||||
SourcePort: item.ConnectionInfo.ClientPort,
|
||||
DestinationPort: item.ConnectionInfo.ServerPort,
|
||||
IsOutgoing: item.ConnectionInfo.IsOutgoing,
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -172,25 +172,31 @@ func (d dissecting) Analyze(item *api.OutputChannelItem, entryId string, resolve
|
||||
elapsedTime := item.Pair.Response.CaptureTime.Sub(item.Pair.Request.CaptureTime).Round(time.Millisecond).Milliseconds()
|
||||
entryBytes, _ := json.Marshal(item.Pair)
|
||||
return &api.MizuEntry{
|
||||
ProtocolName: protocol.Name,
|
||||
ProtocolVersion: item.Protocol.Version,
|
||||
EntryId: entryId,
|
||||
Entry: string(entryBytes),
|
||||
Url: fmt.Sprintf("%s%s", service, path),
|
||||
Method: reqDetails["method"].(string),
|
||||
Status: int(resDetails["status"].(float64)),
|
||||
RequestSenderIp: item.ConnectionInfo.ClientIP,
|
||||
Service: service,
|
||||
Timestamp: item.Timestamp,
|
||||
ElapsedTime: elapsedTime,
|
||||
Path: path,
|
||||
ResolvedSource: resolvedSource,
|
||||
ResolvedDestination: resolvedDestination,
|
||||
SourceIp: item.ConnectionInfo.ClientIP,
|
||||
DestinationIp: item.ConnectionInfo.ServerIP,
|
||||
SourcePort: item.ConnectionInfo.ClientPort,
|
||||
DestinationPort: item.ConnectionInfo.ServerPort,
|
||||
IsOutgoing: item.ConnectionInfo.IsOutgoing,
|
||||
ProtocolName: protocol.Name,
|
||||
ProtocolLongName: protocol.LongName,
|
||||
ProtocolAbbreviation: protocol.Abbreviation,
|
||||
ProtocolVersion: item.Protocol.Version,
|
||||
ProtocolBackgroundColor: protocol.BackgroundColor,
|
||||
ProtocolForegroundColor: protocol.ForegroundColor,
|
||||
ProtocolFontSize: protocol.FontSize,
|
||||
ProtocolReferenceLink: protocol.ReferenceLink,
|
||||
EntryId: entryId,
|
||||
Entry: string(entryBytes),
|
||||
Url: fmt.Sprintf("%s%s", service, path),
|
||||
Method: reqDetails["method"].(string),
|
||||
Status: int(resDetails["status"].(float64)),
|
||||
RequestSenderIp: item.ConnectionInfo.ClientIP,
|
||||
Service: service,
|
||||
Timestamp: item.Timestamp,
|
||||
ElapsedTime: elapsedTime,
|
||||
Path: path,
|
||||
ResolvedSource: resolvedSource,
|
||||
ResolvedDestination: resolvedDestination,
|
||||
SourceIp: item.ConnectionInfo.ClientIP,
|
||||
DestinationIp: item.ConnectionInfo.ServerIP,
|
||||
SourcePort: item.ConnectionInfo.ClientPort,
|
||||
DestinationPort: item.ConnectionInfo.ServerPort,
|
||||
IsOutgoing: item.ConnectionInfo.IsOutgoing,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -142,25 +142,31 @@ func (d dissecting) Analyze(item *api.OutputChannelItem, entryId string, resolve
|
||||
elapsedTime := item.Pair.Response.CaptureTime.Sub(item.Pair.Request.CaptureTime).Round(time.Millisecond).Milliseconds()
|
||||
entryBytes, _ := json.Marshal(item.Pair)
|
||||
return &api.MizuEntry{
|
||||
ProtocolName: _protocol.Name,
|
||||
ProtocolVersion: _protocol.Version,
|
||||
EntryId: entryId,
|
||||
Entry: string(entryBytes),
|
||||
Url: fmt.Sprintf("%s%s", service, summary),
|
||||
Method: apiNames[apiKey],
|
||||
Status: 0,
|
||||
RequestSenderIp: item.ConnectionInfo.ClientIP,
|
||||
Service: service,
|
||||
Timestamp: item.Timestamp,
|
||||
ElapsedTime: elapsedTime,
|
||||
Path: summary,
|
||||
ResolvedSource: resolvedSource,
|
||||
ResolvedDestination: resolvedDestination,
|
||||
SourceIp: item.ConnectionInfo.ClientIP,
|
||||
DestinationIp: item.ConnectionInfo.ServerIP,
|
||||
SourcePort: item.ConnectionInfo.ClientPort,
|
||||
DestinationPort: item.ConnectionInfo.ServerPort,
|
||||
IsOutgoing: item.ConnectionInfo.IsOutgoing,
|
||||
ProtocolName: _protocol.Name,
|
||||
ProtocolLongName: _protocol.LongName,
|
||||
ProtocolAbbreviation: _protocol.Abbreviation,
|
||||
ProtocolVersion: _protocol.Version,
|
||||
ProtocolBackgroundColor: _protocol.BackgroundColor,
|
||||
ProtocolForegroundColor: _protocol.ForegroundColor,
|
||||
ProtocolFontSize: _protocol.FontSize,
|
||||
ProtocolReferenceLink: _protocol.ReferenceLink,
|
||||
EntryId: entryId,
|
||||
Entry: string(entryBytes),
|
||||
Url: fmt.Sprintf("%s%s", service, summary),
|
||||
Method: apiNames[apiKey],
|
||||
Status: 0,
|
||||
RequestSenderIp: item.ConnectionInfo.ClientIP,
|
||||
Service: service,
|
||||
Timestamp: item.Timestamp,
|
||||
ElapsedTime: elapsedTime,
|
||||
Path: summary,
|
||||
ResolvedSource: resolvedSource,
|
||||
ResolvedDestination: resolvedDestination,
|
||||
SourceIp: item.ConnectionInfo.ClientIP,
|
||||
DestinationIp: item.ConnectionInfo.ServerIP,
|
||||
SourcePort: item.ConnectionInfo.ClientPort,
|
||||
DestinationPort: item.ConnectionInfo.ServerPort,
|
||||
IsOutgoing: item.ConnectionInfo.IsOutgoing,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ var staleTimeoutSeconds = flag.Int("staletimout", 120, "Max time in seconds to k
|
||||
|
||||
var memprofile = flag.String("memprofile", "", "Write memory profile")
|
||||
|
||||
var statsTracker = StatsTracker{}
|
||||
var appStats = api.AppStats{}
|
||||
|
||||
// global
|
||||
var stats struct {
|
||||
@@ -152,8 +152,8 @@ type Context struct {
|
||||
CaptureInfo gopacket.CaptureInfo
|
||||
}
|
||||
|
||||
func GetStats() AppStats {
|
||||
return statsTracker.appStats
|
||||
func GetStats() api.AppStats {
|
||||
return appStats
|
||||
}
|
||||
|
||||
func (c *Context) GetCaptureInfo() gopacket.CaptureInfo {
|
||||
@@ -225,8 +225,8 @@ func closeTimedoutTcpStreamChannels() {
|
||||
if stream.superIdentifier.Protocol == nil {
|
||||
if !stream.isClosed && time.Now().After(streamWrapper.createdAt.Add(TcpStreamChannelTimeoutMs)) {
|
||||
stream.Close()
|
||||
statsTracker.incDroppedTcpStreams()
|
||||
rlog.Debugf("Dropped an unidentified TCP stream because of timeout. Total dropped: %d Total Goroutines: %d Timeout (ms): %d\n", statsTracker.appStats.DroppedTcpStreams, runtime.NumGoroutine(), TcpStreamChannelTimeoutMs/1000000)
|
||||
appStats.IncDroppedTcpStreams()
|
||||
rlog.Debugf("Dropped an unidentified TCP stream because of timeout. Total dropped: %d Total Goroutines: %d Timeout (ms): %d\n", appStats.DroppedTcpStreams, runtime.NumGoroutine(), TcpStreamChannelTimeoutMs/1000000)
|
||||
}
|
||||
} else {
|
||||
if !stream.superIdentifier.IsClosedOthers {
|
||||
@@ -328,10 +328,11 @@ func startPassiveTapper(outputItems chan *api.OutputChannelItem) {
|
||||
source.Lazy = *lazy
|
||||
source.NoCopy = true
|
||||
rlog.Info("Starting to read packets")
|
||||
statsTracker.setStartTime(time.Now())
|
||||
appStats.SetStartTime(time.Now())
|
||||
defragger := ip4defrag.NewIPv4Defragmenter()
|
||||
|
||||
var emitter api.Emitter = &api.Emitting{
|
||||
AppStats: &appStats,
|
||||
OutputChannel: outputItems,
|
||||
}
|
||||
|
||||
@@ -374,7 +375,7 @@ func startPassiveTapper(outputItems chan *api.OutputChannelItem) {
|
||||
errorsSummery := fmt.Sprintf("%v", errorsMap)
|
||||
errorsMapMutex.Unlock()
|
||||
log.Printf("%v (errors: %v, errTypes:%v) - Errors Summary: %s",
|
||||
time.Since(statsTracker.appStats.StartTime),
|
||||
time.Since(appStats.StartTime),
|
||||
nErrors,
|
||||
errorMapLen,
|
||||
errorsSummery,
|
||||
@@ -397,7 +398,7 @@ func startPassiveTapper(outputItems chan *api.OutputChannelItem) {
|
||||
cleanStats.closed,
|
||||
cleanStats.deleted,
|
||||
)
|
||||
currentAppStats := statsTracker.dumpStats()
|
||||
currentAppStats := appStats.DumpStats()
|
||||
appStatsJSON, _ := json.Marshal(currentAppStats)
|
||||
log.Printf("app stats - %v", string(appStatsJSON))
|
||||
}
|
||||
@@ -415,10 +416,10 @@ func startPassiveTapper(outputItems chan *api.OutputChannelItem) {
|
||||
rlog.Debugf("Error:", err)
|
||||
continue
|
||||
}
|
||||
packetsCount := statsTracker.incPacketsCount()
|
||||
packetsCount := appStats.IncPacketsCount()
|
||||
rlog.Debugf("PACKET #%d", packetsCount)
|
||||
data := packet.Data()
|
||||
statsTracker.updateProcessedBytes(int64(len(data)))
|
||||
appStats.UpdateProcessedBytes(uint64(len(data)))
|
||||
if *hexdumppkt {
|
||||
rlog.Debugf("Packet content (%d/0x%x) - %s", len(data), len(data), hex.Dump(data))
|
||||
}
|
||||
@@ -452,7 +453,7 @@ func startPassiveTapper(outputItems chan *api.OutputChannelItem) {
|
||||
|
||||
tcp := packet.Layer(layers.LayerTypeTCP)
|
||||
if tcp != nil {
|
||||
statsTracker.incTcpPacketsCount()
|
||||
appStats.IncTcpPacketsCount()
|
||||
tcp := tcp.(*layers.TCP)
|
||||
if *checksum {
|
||||
err := tcp.SetNetworkLayerForChecksum(packet.NetworkLayer())
|
||||
@@ -470,15 +471,15 @@ func startPassiveTapper(outputItems chan *api.OutputChannelItem) {
|
||||
assemblerMutex.Unlock()
|
||||
}
|
||||
|
||||
done := *maxcount > 0 && statsTracker.appStats.PacketsCount >= *maxcount
|
||||
done := *maxcount > 0 && int64(appStats.PacketsCount) >= *maxcount
|
||||
if done {
|
||||
errorsMapMutex.Lock()
|
||||
errorMapLen := len(errorsMap)
|
||||
errorsMapMutex.Unlock()
|
||||
log.Printf("Processed %v packets (%v bytes) in %v (errors: %v, errTypes:%v)",
|
||||
statsTracker.appStats.PacketsCount,
|
||||
statsTracker.appStats.ProcessedBytes,
|
||||
time.Since(statsTracker.appStats.StartTime),
|
||||
appStats.PacketsCount,
|
||||
appStats.ProcessedBytes,
|
||||
time.Since(appStats.StartTime),
|
||||
nErrors,
|
||||
errorMapLen)
|
||||
}
|
||||
|
||||
@@ -1,117 +0,0 @@
|
||||
package tap
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
type AppStats struct {
|
||||
StartTime time.Time `json:"-"`
|
||||
ProcessedBytes int64 `json:"processedBytes"`
|
||||
PacketsCount int64 `json:"packetsCount"`
|
||||
TcpPacketsCount int64 `json:"tcpPacketsCount"`
|
||||
ReassembledTcpPayloadsCount int64 `json:"reassembledTcpPayloadsCount"`
|
||||
TlsConnectionsCount int64 `json:"tlsConnectionsCount"`
|
||||
MatchedPairs int64 `json:"matchedPairs"`
|
||||
DroppedTcpStreams int64 `json:"droppedTcpStreams"`
|
||||
}
|
||||
|
||||
type StatsTracker struct {
|
||||
appStats AppStats
|
||||
processedBytesMutex sync.Mutex
|
||||
packetsCountMutex sync.Mutex
|
||||
tcpPacketsCountMutex sync.Mutex
|
||||
reassembledTcpPayloadsCountMutex sync.Mutex
|
||||
tlsConnectionsCountMutex sync.Mutex
|
||||
matchedPairsMutex sync.Mutex
|
||||
droppedTcpStreamsMutex sync.Mutex
|
||||
}
|
||||
|
||||
func (st *StatsTracker) incMatchedPairs() {
|
||||
st.matchedPairsMutex.Lock()
|
||||
st.appStats.MatchedPairs++
|
||||
st.matchedPairsMutex.Unlock()
|
||||
}
|
||||
|
||||
func (st *StatsTracker) incDroppedTcpStreams() {
|
||||
st.droppedTcpStreamsMutex.Lock()
|
||||
st.appStats.DroppedTcpStreams++
|
||||
st.droppedTcpStreamsMutex.Unlock()
|
||||
}
|
||||
|
||||
func (st *StatsTracker) incPacketsCount() int64 {
|
||||
st.packetsCountMutex.Lock()
|
||||
st.appStats.PacketsCount++
|
||||
currentPacketsCount := st.appStats.PacketsCount
|
||||
st.packetsCountMutex.Unlock()
|
||||
return currentPacketsCount
|
||||
}
|
||||
|
||||
func (st *StatsTracker) incTcpPacketsCount() {
|
||||
st.tcpPacketsCountMutex.Lock()
|
||||
st.appStats.TcpPacketsCount++
|
||||
st.tcpPacketsCountMutex.Unlock()
|
||||
}
|
||||
|
||||
func (st *StatsTracker) incReassembledTcpPayloadsCount() {
|
||||
st.reassembledTcpPayloadsCountMutex.Lock()
|
||||
st.appStats.ReassembledTcpPayloadsCount++
|
||||
st.reassembledTcpPayloadsCountMutex.Unlock()
|
||||
}
|
||||
|
||||
func (st *StatsTracker) incTlsConnectionsCount() {
|
||||
st.tlsConnectionsCountMutex.Lock()
|
||||
st.appStats.TlsConnectionsCount++
|
||||
st.tlsConnectionsCountMutex.Unlock()
|
||||
}
|
||||
|
||||
func (st *StatsTracker) updateProcessedBytes(size int64) {
|
||||
st.processedBytesMutex.Lock()
|
||||
st.appStats.ProcessedBytes += size
|
||||
st.processedBytesMutex.Unlock()
|
||||
}
|
||||
|
||||
func (st *StatsTracker) setStartTime(startTime time.Time) {
|
||||
st.appStats.StartTime = startTime
|
||||
}
|
||||
|
||||
func (st *StatsTracker) dumpStats() *AppStats {
|
||||
currentAppStats := &AppStats{StartTime: st.appStats.StartTime}
|
||||
|
||||
st.processedBytesMutex.Lock()
|
||||
currentAppStats.ProcessedBytes = st.appStats.ProcessedBytes
|
||||
st.appStats.ProcessedBytes = 0
|
||||
st.processedBytesMutex.Unlock()
|
||||
|
||||
st.packetsCountMutex.Lock()
|
||||
currentAppStats.PacketsCount = st.appStats.PacketsCount
|
||||
st.appStats.PacketsCount = 0
|
||||
st.packetsCountMutex.Unlock()
|
||||
|
||||
st.tcpPacketsCountMutex.Lock()
|
||||
currentAppStats.TcpPacketsCount = st.appStats.TcpPacketsCount
|
||||
st.appStats.TcpPacketsCount = 0
|
||||
st.tcpPacketsCountMutex.Unlock()
|
||||
|
||||
st.reassembledTcpPayloadsCountMutex.Lock()
|
||||
currentAppStats.ReassembledTcpPayloadsCount = st.appStats.ReassembledTcpPayloadsCount
|
||||
st.appStats.ReassembledTcpPayloadsCount = 0
|
||||
st.reassembledTcpPayloadsCountMutex.Unlock()
|
||||
|
||||
st.tlsConnectionsCountMutex.Lock()
|
||||
currentAppStats.TlsConnectionsCount = st.appStats.TlsConnectionsCount
|
||||
st.appStats.TlsConnectionsCount = 0
|
||||
st.tlsConnectionsCountMutex.Unlock()
|
||||
|
||||
st.matchedPairsMutex.Lock()
|
||||
currentAppStats.MatchedPairs = st.appStats.MatchedPairs
|
||||
st.appStats.MatchedPairs = 0
|
||||
st.matchedPairsMutex.Unlock()
|
||||
|
||||
st.droppedTcpStreamsMutex.Lock()
|
||||
currentAppStats.DroppedTcpStreams = st.appStats.DroppedTcpStreams
|
||||
st.appStats.DroppedTcpStreams = 0
|
||||
st.droppedTcpStreamsMutex.Unlock()
|
||||
|
||||
return currentAppStats
|
||||
}
|
||||
@@ -147,7 +147,7 @@ func (t *tcpStream) ReassembledSG(sg reassembly.ScatterGather, ac reassembly.Ass
|
||||
if length > 0 {
|
||||
// This is where we pass the reassembled information onwards
|
||||
// This channel is read by an tcpReader object
|
||||
statsTracker.incReassembledTcpPayloadsCount()
|
||||
appStats.IncReassembledTcpPayloadsCount()
|
||||
timestamp := ac.GetCaptureInfo().Timestamp
|
||||
if dir == reassembly.TCPDirClientToServer {
|
||||
for i := range t.clients {
|
||||
|
||||
@@ -62,8 +62,8 @@ func (factory *tcpStreamFactory) New(net, transport gopacket.Flow, tcp *layers.T
|
||||
}
|
||||
if stream.isTapTarget {
|
||||
if runtime.NumGoroutine() > maxNumberOfGoroutines {
|
||||
statsTracker.incDroppedTcpStreams()
|
||||
rlog.Debugf("Dropped a TCP stream because of load. Total dropped: %d Total Goroutines: %d\n", statsTracker.appStats.DroppedTcpStreams, runtime.NumGoroutine())
|
||||
appStats.IncDroppedTcpStreams()
|
||||
rlog.Debugf("Dropped a TCP stream because of load. Total dropped: %d Total Goroutines: %d\n", appStats.DroppedTcpStreams, runtime.NumGoroutine())
|
||||
return stream
|
||||
}
|
||||
streamId++
|
||||
|
||||
22792
ui/package-lock.json
generated
22792
ui/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -12,8 +12,8 @@
|
||||
"@types/node": "^12.20.10",
|
||||
"@types/react": "^17.0.3",
|
||||
"@types/react-dom": "^17.0.3",
|
||||
"jsonpath": "^1.1.1",
|
||||
"axios": "^0.21.1",
|
||||
"jsonpath": "^1.1.1",
|
||||
"node-sass": "^5.0.0",
|
||||
"numeral": "^2.0.6",
|
||||
"protobuf-decoder": "^0.1.0",
|
||||
@@ -21,7 +21,7 @@
|
||||
"react-copy-to-clipboard": "^5.0.3",
|
||||
"react-dom": "^17.0.2",
|
||||
"react-scripts": "4.0.3",
|
||||
"react-scrollable-feed": "^1.3.0",
|
||||
"react-scrollable-feed-virtualized": "^1.4.2",
|
||||
"react-syntax-highlighter": "^15.4.3",
|
||||
"typescript": "^4.2.4",
|
||||
"web-vitals": "^1.1.1"
|
||||
|
||||
@@ -2,7 +2,7 @@ import {EntryItem} from "./EntryListItem/EntryListItem";
|
||||
import React, {useCallback, useEffect, useMemo, useRef, useState} from "react";
|
||||
import styles from './style/EntriesList.module.sass';
|
||||
import spinner from './assets/spinner.svg';
|
||||
import ScrollableFeed from "react-scrollable-feed";
|
||||
import ScrollableFeedVirtualized from "react-scrollable-feed-virtualized";
|
||||
import {StatusType} from "./Filters";
|
||||
import Api from "../helpers/api";
|
||||
import down from "./assets/downImg.svg";
|
||||
@@ -54,8 +54,8 @@ export const EntriesList: React.FC<EntriesListProps> = ({entries, setEntries, fo
|
||||
const filterEntries = useCallback((entry) => {
|
||||
if(methodsFilter.length > 0 && !methodsFilter.includes(entry.method.toLowerCase())) return;
|
||||
if(pathFilter && entry.path?.toLowerCase()?.indexOf(pathFilter) === -1) return;
|
||||
if(statusFilter.includes(StatusType.SUCCESS) && entry.status_code >= 400) return;
|
||||
if(statusFilter.includes(StatusType.ERROR) && entry.status_code < 400) return;
|
||||
if(statusFilter.includes(StatusType.SUCCESS) && entry.statusCode >= 400) return;
|
||||
if(statusFilter.includes(StatusType.ERROR) && entry.statusCode < 400) return;
|
||||
return entry;
|
||||
},[methodsFilter, pathFilter, statusFilter])
|
||||
|
||||
@@ -77,9 +77,6 @@ export const EntriesList: React.FC<EntriesListProps> = ({entries, setEntries, fo
|
||||
}
|
||||
setIsLoadingTop(false);
|
||||
const newEntries = [...data, ...entries];
|
||||
if(newEntries.length >= 1000) {
|
||||
newEntries.splice(1000);
|
||||
}
|
||||
setEntries(newEntries);
|
||||
|
||||
if(scrollTo) {
|
||||
@@ -100,10 +97,6 @@ export const EntriesList: React.FC<EntriesListProps> = ({entries, setEntries, fo
|
||||
}
|
||||
scrollTo = document.getElementById(filteredEntries?.[filteredEntries.length -1]?.id);
|
||||
let newEntries = [...entries, ...data];
|
||||
if(newEntries.length >= 1000) {
|
||||
setNoMoreDataTop(false);
|
||||
newEntries = newEntries.slice(-1000);
|
||||
}
|
||||
setEntries(newEntries);
|
||||
if(scrollTo) {
|
||||
scrollTo.scrollIntoView({behavior: "smooth"});
|
||||
@@ -116,19 +109,20 @@ export const EntriesList: React.FC<EntriesListProps> = ({entries, setEntries, fo
|
||||
{isLoadingTop && <div className={styles.spinnerContainer}>
|
||||
<img alt="spinner" src={spinner} style={{height: 25}}/>
|
||||
</div>}
|
||||
<ScrollableFeed ref={scrollableRef} onScroll={(isAtBottom) => onScrollEvent(isAtBottom)}>
|
||||
<ScrollableFeedVirtualized ref={scrollableRef} itemHeight={48} marginTop={10} onScroll={(isAtBottom) => onScrollEvent(isAtBottom)}>
|
||||
{noMoreDataTop && !connectionOpen && <div id="noMoreDataTop" className={styles.noMoreDataAvailable}>No more data available</div>}
|
||||
{filteredEntries.map(entry => <EntryItem key={entry.id}
|
||||
entry={entry}
|
||||
setFocusedEntryId={setFocusedEntryId}
|
||||
isSelected={focusedEntryId === entry.id}/>)}
|
||||
{!connectionOpen && !noMoreDataBottom && <div className={styles.fetchButtonContainer}>
|
||||
<div className={styles.styledButton} onClick={() => getNewEntries()}>Fetch more entries</div>
|
||||
</div>}
|
||||
</ScrollableFeed>
|
||||
<button type="button"
|
||||
className={`${styles.btnLive} ${scrollableList ? styles.showButton : styles.hideButton}`}
|
||||
onClick={(_) => scrollableRef.current.scrollToBottom()}>
|
||||
isSelected={focusedEntryId === entry.id}
|
||||
style={{}}/>)}
|
||||
</ScrollableFeedVirtualized>
|
||||
{!connectionOpen && !noMoreDataBottom && <div className={styles.fetchButtonContainer}>
|
||||
<div className={styles.styledButton} onClick={() => getNewEntries()}>Fetch more entries</div>
|
||||
</div>}
|
||||
<button type="button"
|
||||
className={`${styles.btnLive} ${scrollableList ? styles.showButton : styles.hideButton}`}
|
||||
onClick={(_) => scrollableRef.current.jumpToBottom()}>
|
||||
<img alt="down" src={down} />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -72,7 +72,7 @@ export const EntryDetailed: React.FC<EntryDetailedProps> = ({entryData}) => {
|
||||
/>
|
||||
{entryData.data && <EntrySummary data={entryData.data}/>}
|
||||
<>
|
||||
{entryData.data && <EntryViewer representation={entryData.representation} color={entryData.protocol.background_color}/>}
|
||||
{entryData.data && <EntryViewer representation={entryData.representation} color={entryData.protocol.backgroundColor}/>}
|
||||
</>
|
||||
</>
|
||||
};
|
||||
|
||||
@@ -16,14 +16,14 @@ interface Entry {
|
||||
summary: string,
|
||||
service: string,
|
||||
id: string,
|
||||
status_code?: number;
|
||||
statusCode?: number;
|
||||
url?: string;
|
||||
timestamp: Date;
|
||||
source_ip: string,
|
||||
source_port: string,
|
||||
destination_ip: string,
|
||||
destination_port: string,
|
||||
isOutgoing?: boolean;
|
||||
sourceIp: string,
|
||||
sourcePort: string,
|
||||
destinationIp: string,
|
||||
destinationPort: string,
|
||||
isOutgoing?: boolean;
|
||||
latency: number;
|
||||
rules: Rules;
|
||||
}
|
||||
@@ -38,10 +38,11 @@ interface EntryProps {
|
||||
entry: Entry;
|
||||
setFocusedEntryId: (id: string) => void;
|
||||
isSelected?: boolean;
|
||||
style: object;
|
||||
}
|
||||
|
||||
export const EntryItem: React.FC<EntryProps> = ({entry, setFocusedEntryId, isSelected}) => {
|
||||
const classification = getClassification(entry.status_code)
|
||||
export const EntryItem: React.FC<EntryProps> = ({entry, setFocusedEntryId, isSelected, style}) => {
|
||||
const classification = getClassification(entry.statusCode)
|
||||
let ingoingIcon;
|
||||
let outgoingIcon;
|
||||
switch(classification) {
|
||||
@@ -103,11 +104,17 @@ export const EntryItem: React.FC<EntryProps> = ({entry, setFocusedEntryId, isSel
|
||||
className={`${styles.row}
|
||||
${isSelected ? styles.rowSelected : backgroundColor}`}
|
||||
onClick={() => setFocusedEntryId(entry.id)}
|
||||
style={{border: isSelected ? `1px ${entry.protocol.background_color} solid` : "1px transparent solid"}}
|
||||
style={{
|
||||
border: isSelected ? `1px ${entry.protocol.backgroundColor} solid` : "1px transparent solid",
|
||||
position: "absolute",
|
||||
top: style['top'],
|
||||
marginTop: style['marginTop'],
|
||||
width: "calc(100% - 25px)",
|
||||
}}
|
||||
>
|
||||
<Protocol protocol={entry.protocol} horizontal={false}/>
|
||||
{((entry.protocol.name === "http" && "status_code" in entry) || entry.status_code !== 0) && <div>
|
||||
<StatusCode statusCode={entry.status_code}/>
|
||||
{((entry.protocol.name === "http" && "statusCode" in entry) || entry.statusCode !== 0) && <div>
|
||||
<StatusCode statusCode={entry.statusCode}/>
|
||||
</div>}
|
||||
<div className={styles.endpointServiceContainer}>
|
||||
<EndpointPath method={entry.method} path={entry.summary}/>
|
||||
@@ -116,13 +123,13 @@ export const EntryItem: React.FC<EntryProps> = ({entry, setFocusedEntryId, isSel
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles.directionContainer}>
|
||||
<span className={styles.port} title="Source Port">{entry.source_port}</span>
|
||||
<span className={styles.port} title="Source Port">{entry.sourcePort}</span>
|
||||
{entry.isOutgoing ?
|
||||
<img src={outgoingIcon} alt="Ingoing traffic" title="Ingoing"/>
|
||||
:
|
||||
<img src={ingoingIcon} alt="Outgoing traffic" title="Outgoing"/>
|
||||
}
|
||||
<span className={styles.port} title="Destination Port">{entry.destination_port}</span>
|
||||
<span className={styles.port} title="Destination Port">{entry.destinationPort}</span>
|
||||
</div>
|
||||
<div className={styles.timestamp}>
|
||||
<span title="Timestamp">
|
||||
|
||||
@@ -86,10 +86,6 @@ export const TrafficPage: React.FC<TrafficPageProps> = ({setAnalyzeStatus, onTLS
|
||||
}
|
||||
if (!focusedEntryId) setFocusedEntryId(entry.id)
|
||||
let newEntries = [...entries];
|
||||
if (entries.length === 1000) {
|
||||
newEntries = newEntries.splice(1);
|
||||
setNoMoreDataTop(false);
|
||||
}
|
||||
setEntries([...newEntries, entry])
|
||||
if(listEntry.current) {
|
||||
if(isScrollable(listEntry.current.firstChild)) {
|
||||
|
||||
@@ -3,12 +3,12 @@ import styles from './style/Protocol.module.sass';
|
||||
|
||||
export interface ProtocolInterface {
|
||||
name: string
|
||||
long_name: string
|
||||
longName: string
|
||||
abbreviation: string
|
||||
background_color: string
|
||||
foreground_color: string
|
||||
font_size: number
|
||||
reference_link: string
|
||||
backgroundColor: string
|
||||
foregroundColor: string
|
||||
fontSize: number
|
||||
referenceLink: string
|
||||
ports: string[]
|
||||
inbound_ports: string
|
||||
}
|
||||
@@ -20,29 +20,29 @@ interface ProtocolProps {
|
||||
|
||||
const Protocol: React.FC<ProtocolProps> = ({protocol, horizontal}) => {
|
||||
if (horizontal) {
|
||||
return <a target="_blank" rel="noopener noreferrer" href={protocol.reference_link}>
|
||||
return <a target="_blank" rel="noopener noreferrer" href={protocol.referenceLink}>
|
||||
<span
|
||||
className={`${styles.base} ${styles.horizontal}`}
|
||||
style={{
|
||||
backgroundColor: protocol.background_color,
|
||||
color: protocol.foreground_color,
|
||||
backgroundColor: protocol.backgroundColor,
|
||||
color: protocol.foregroundColor,
|
||||
fontSize: 13,
|
||||
}}
|
||||
title={protocol.abbreviation}
|
||||
>
|
||||
{protocol.long_name}
|
||||
{protocol.longName}
|
||||
</span>
|
||||
</a>
|
||||
} else {
|
||||
return <a target="_blank" rel="noopener noreferrer" href={protocol.reference_link}>
|
||||
return <a target="_blank" rel="noopener noreferrer" href={protocol.referenceLink}>
|
||||
<span
|
||||
className={`${styles.base} ${styles.vertical}`}
|
||||
style={{
|
||||
backgroundColor: protocol.background_color,
|
||||
color: protocol.foreground_color,
|
||||
fontSize: protocol.font_size,
|
||||
backgroundColor: protocol.backgroundColor,
|
||||
color: protocol.foregroundColor,
|
||||
fontSize: protocol.fontSize,
|
||||
}}
|
||||
title={protocol.long_name}
|
||||
title={protocol.longName}
|
||||
>
|
||||
{protocol.abbreviation}
|
||||
</span>
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
flex-direction: column
|
||||
overflow: hidden
|
||||
flex-grow: 1
|
||||
padding-top: 20px
|
||||
|
||||
.footer
|
||||
display: flex
|
||||
|
||||
Reference in New Issue
Block a user