mirror of
https://github.com/ScuroNeko/mtg.git
synced 2026-08-31 14:54:01 +03:00
Rework events
This commit is contained in:
+17
-49
@@ -39,11 +39,7 @@ func (suite *EventStreamTestSuite) SetupTest() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (suite *EventStreamTestSuite) TestEventStart() {
|
func (suite *EventStreamTestSuite) TestEventStart() {
|
||||||
evt := mtglib.EventStart{
|
evt := mtglib.NewEventStart("connID", net.ParseIP("10.0.0.1"))
|
||||||
CreatedAt: time.Now(),
|
|
||||||
ConnID: "connID",
|
|
||||||
RemoteIP: net.ParseIP("10.0.0.1"),
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, v := range []*ObserverMock{suite.observerMock1, suite.observerMock2} {
|
for _, v := range []*ObserverMock{suite.observerMock1, suite.observerMock2} {
|
||||||
v.
|
v.
|
||||||
@@ -52,10 +48,9 @@ func (suite *EventStreamTestSuite) TestEventStart() {
|
|||||||
Run(func(args mock.Arguments) {
|
Run(func(args mock.Arguments) {
|
||||||
caught := args.Get(0).(mtglib.EventStart)
|
caught := args.Get(0).(mtglib.EventStart)
|
||||||
|
|
||||||
suite.Equal(evt.CreatedAt, caught.CreatedAt)
|
|
||||||
suite.Equal(evt.ConnID, caught.ConnID)
|
|
||||||
suite.Equal(evt.RemoteIP.String(), caught.RemoteIP.String())
|
suite.Equal(evt.RemoteIP.String(), caught.RemoteIP.String())
|
||||||
suite.Equal(evt.StreamID(), caught.StreamID())
|
suite.Equal(evt.StreamID(), caught.StreamID())
|
||||||
|
suite.Equal(evt.Timestamp(), caught.Timestamp())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,12 +59,7 @@ func (suite *EventStreamTestSuite) TestEventStart() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (suite *EventStreamTestSuite) TestEventConnectedToDC() {
|
func (suite *EventStreamTestSuite) TestEventConnectedToDC() {
|
||||||
evt := mtglib.EventConnectedToDC{
|
evt := mtglib.NewEventConnectedToDC("connID", net.ParseIP("10.0.0.1"), 3)
|
||||||
CreatedAt: time.Now(),
|
|
||||||
ConnID: "connID",
|
|
||||||
RemoteIP: net.ParseIP("10.0.0.1"),
|
|
||||||
DC: 3,
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, v := range []*ObserverMock{suite.observerMock1, suite.observerMock2} {
|
for _, v := range []*ObserverMock{suite.observerMock1, suite.observerMock2} {
|
||||||
v.
|
v.
|
||||||
@@ -78,11 +68,10 @@ func (suite *EventStreamTestSuite) TestEventConnectedToDC() {
|
|||||||
Run(func(args mock.Arguments) {
|
Run(func(args mock.Arguments) {
|
||||||
caught := args.Get(0).(mtglib.EventConnectedToDC)
|
caught := args.Get(0).(mtglib.EventConnectedToDC)
|
||||||
|
|
||||||
suite.Equal(evt.CreatedAt, caught.CreatedAt)
|
|
||||||
suite.Equal(evt.ConnID, caught.ConnID)
|
|
||||||
suite.Equal(evt.RemoteIP.String(), caught.RemoteIP.String())
|
suite.Equal(evt.RemoteIP.String(), caught.RemoteIP.String())
|
||||||
suite.Equal(evt.StreamID(), caught.StreamID())
|
suite.Equal(evt.StreamID(), caught.StreamID())
|
||||||
suite.Equal(evt.DC, caught.DC)
|
suite.Equal(evt.DC, caught.DC)
|
||||||
|
suite.Equal(evt.Timestamp(), caught.Timestamp())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,10 +80,7 @@ func (suite *EventStreamTestSuite) TestEventConnectedToDC() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (suite *EventStreamTestSuite) TestEventDomainFronting() {
|
func (suite *EventStreamTestSuite) TestEventDomainFronting() {
|
||||||
evt := mtglib.EventDomainFronting{
|
evt := mtglib.NewEventDomainFronting("connID")
|
||||||
CreatedAt: time.Now(),
|
|
||||||
ConnID: "connID",
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, v := range []*ObserverMock{suite.observerMock1, suite.observerMock2} {
|
for _, v := range []*ObserverMock{suite.observerMock1, suite.observerMock2} {
|
||||||
v.
|
v.
|
||||||
@@ -103,9 +89,8 @@ func (suite *EventStreamTestSuite) TestEventDomainFronting() {
|
|||||||
Run(func(args mock.Arguments) {
|
Run(func(args mock.Arguments) {
|
||||||
caught := args.Get(0).(mtglib.EventDomainFronting)
|
caught := args.Get(0).(mtglib.EventDomainFronting)
|
||||||
|
|
||||||
suite.Equal(evt.CreatedAt, caught.CreatedAt)
|
|
||||||
suite.Equal(evt.ConnID, caught.ConnID)
|
|
||||||
suite.Equal(evt.StreamID(), caught.StreamID())
|
suite.Equal(evt.StreamID(), caught.StreamID())
|
||||||
|
suite.Equal(evt.Timestamp(), caught.Timestamp())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,12 +99,7 @@ func (suite *EventStreamTestSuite) TestEventDomainFronting() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (suite *EventStreamTestSuite) TestEventTraffic() {
|
func (suite *EventStreamTestSuite) TestEventTraffic() {
|
||||||
evt := mtglib.EventTraffic{
|
evt := mtglib.NewEventTraffic("connID", 1024, true)
|
||||||
CreatedAt: time.Now(),
|
|
||||||
ConnID: "connID",
|
|
||||||
Traffic: 1024,
|
|
||||||
IsRead: true,
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, v := range []*ObserverMock{suite.observerMock1, suite.observerMock2} {
|
for _, v := range []*ObserverMock{suite.observerMock1, suite.observerMock2} {
|
||||||
v.
|
v.
|
||||||
@@ -128,9 +108,8 @@ func (suite *EventStreamTestSuite) TestEventTraffic() {
|
|||||||
Run(func(args mock.Arguments) {
|
Run(func(args mock.Arguments) {
|
||||||
caught := args.Get(0).(mtglib.EventTraffic)
|
caught := args.Get(0).(mtglib.EventTraffic)
|
||||||
|
|
||||||
suite.Equal(evt.CreatedAt, caught.CreatedAt)
|
|
||||||
suite.Equal(evt.ConnID, caught.ConnID)
|
|
||||||
suite.Equal(evt.StreamID(), caught.StreamID())
|
suite.Equal(evt.StreamID(), caught.StreamID())
|
||||||
|
suite.Equal(evt.Timestamp(), caught.Timestamp())
|
||||||
suite.Equal(evt.Traffic, caught.Traffic)
|
suite.Equal(evt.Traffic, caught.Traffic)
|
||||||
suite.Equal(evt.IsRead, caught.IsRead)
|
suite.Equal(evt.IsRead, caught.IsRead)
|
||||||
})
|
})
|
||||||
@@ -141,10 +120,7 @@ func (suite *EventStreamTestSuite) TestEventTraffic() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (suite *EventStreamTestSuite) TestEventFinish() {
|
func (suite *EventStreamTestSuite) TestEventFinish() {
|
||||||
evt := mtglib.EventFinish{
|
evt := mtglib.NewEventFinish("connID")
|
||||||
CreatedAt: time.Now(),
|
|
||||||
ConnID: "connID",
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, v := range []*ObserverMock{suite.observerMock1, suite.observerMock2} {
|
for _, v := range []*ObserverMock{suite.observerMock1, suite.observerMock2} {
|
||||||
v.
|
v.
|
||||||
@@ -153,9 +129,8 @@ func (suite *EventStreamTestSuite) TestEventFinish() {
|
|||||||
Run(func(args mock.Arguments) {
|
Run(func(args mock.Arguments) {
|
||||||
caught := args.Get(0).(mtglib.EventFinish)
|
caught := args.Get(0).(mtglib.EventFinish)
|
||||||
|
|
||||||
suite.Equal(evt.CreatedAt, caught.CreatedAt)
|
|
||||||
suite.Equal(evt.ConnID, caught.ConnID)
|
|
||||||
suite.Equal(evt.StreamID(), caught.StreamID())
|
suite.Equal(evt.StreamID(), caught.StreamID())
|
||||||
|
suite.Equal(evt.Timestamp(), caught.Timestamp())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -164,9 +139,7 @@ func (suite *EventStreamTestSuite) TestEventFinish() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (suite *EventStreamTestSuite) TestEventConcurrencyLimited() {
|
func (suite *EventStreamTestSuite) TestEventConcurrencyLimited() {
|
||||||
evt := mtglib.EventConcurrencyLimited{
|
evt := mtglib.NewEventConcurrencyLimited()
|
||||||
CreatedAt: time.Now(),
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, v := range []*ObserverMock{suite.observerMock1, suite.observerMock2} {
|
for _, v := range []*ObserverMock{suite.observerMock1, suite.observerMock2} {
|
||||||
v.
|
v.
|
||||||
@@ -175,7 +148,8 @@ func (suite *EventStreamTestSuite) TestEventConcurrencyLimited() {
|
|||||||
Run(func(args mock.Arguments) {
|
Run(func(args mock.Arguments) {
|
||||||
caught := args.Get(0).(mtglib.EventConcurrencyLimited)
|
caught := args.Get(0).(mtglib.EventConcurrencyLimited)
|
||||||
|
|
||||||
suite.Equal(evt.CreatedAt, caught.CreatedAt)
|
suite.Equal(evt.Timestamp(), caught.Timestamp())
|
||||||
|
suite.Empty(evt.StreamID())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -184,10 +158,7 @@ func (suite *EventStreamTestSuite) TestEventConcurrencyLimited() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (suite *EventStreamTestSuite) TestEventIPBlocklisted() {
|
func (suite *EventStreamTestSuite) TestEventIPBlocklisted() {
|
||||||
evt := mtglib.EventIPBlocklisted{
|
evt := mtglib.NewEventIPBlocklisted(net.ParseIP("10.0.0.10"))
|
||||||
CreatedAt: time.Now(),
|
|
||||||
RemoteIP: net.ParseIP("10.0.0.10"),
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, v := range []*ObserverMock{suite.observerMock1, suite.observerMock2} {
|
for _, v := range []*ObserverMock{suite.observerMock1, suite.observerMock2} {
|
||||||
v.
|
v.
|
||||||
@@ -196,8 +167,8 @@ func (suite *EventStreamTestSuite) TestEventIPBlocklisted() {
|
|||||||
Run(func(args mock.Arguments) {
|
Run(func(args mock.Arguments) {
|
||||||
caught := args.Get(0).(mtglib.EventIPBlocklisted)
|
caught := args.Get(0).(mtglib.EventIPBlocklisted)
|
||||||
|
|
||||||
suite.Equal(evt.CreatedAt, caught.CreatedAt)
|
|
||||||
suite.Equal(evt.StreamID(), caught.StreamID())
|
suite.Equal(evt.StreamID(), caught.StreamID())
|
||||||
|
suite.Equal(evt.Timestamp(), caught.Timestamp())
|
||||||
suite.Equal(evt.RemoteIP.String(), caught.RemoteIP.String())
|
suite.Equal(evt.RemoteIP.String(), caught.RemoteIP.String())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -207,10 +178,7 @@ func (suite *EventStreamTestSuite) TestEventIPBlocklisted() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (suite *EventStreamTestSuite) TestEventReplayAttack() {
|
func (suite *EventStreamTestSuite) TestEventReplayAttack() {
|
||||||
evt := mtglib.EventReplayAttack{
|
evt := mtglib.NewEventReplayAttack("CONNID")
|
||||||
CreatedAt: time.Now(),
|
|
||||||
ConnID: "CONNID",
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, v := range []*ObserverMock{suite.observerMock1, suite.observerMock2} {
|
for _, v := range []*ObserverMock{suite.observerMock1, suite.observerMock2} {
|
||||||
v.
|
v.
|
||||||
@@ -219,8 +187,8 @@ func (suite *EventStreamTestSuite) TestEventReplayAttack() {
|
|||||||
Run(func(args mock.Arguments) {
|
Run(func(args mock.Arguments) {
|
||||||
caught := args.Get(0).(mtglib.EventReplayAttack)
|
caught := args.Get(0).(mtglib.EventReplayAttack)
|
||||||
|
|
||||||
suite.Equal(evt.CreatedAt, caught.CreatedAt)
|
|
||||||
suite.Equal(evt.StreamID(), caught.StreamID())
|
suite.Equal(evt.StreamID(), caught.StreamID())
|
||||||
|
suite.Equal(evt.Timestamp(), caught.Timestamp())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+8
-37
@@ -4,7 +4,6 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"net"
|
"net"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/9seconds/mtg/v2/events"
|
"github.com/9seconds/mtg/v2/events"
|
||||||
"github.com/9seconds/mtg/v2/mtglib"
|
"github.com/9seconds/mtg/v2/mtglib"
|
||||||
@@ -20,42 +19,14 @@ type NoopTestSuite struct {
|
|||||||
|
|
||||||
func (suite *NoopTestSuite) SetupSuite() {
|
func (suite *NoopTestSuite) SetupSuite() {
|
||||||
suite.testData = map[string]mtglib.Event{
|
suite.testData = map[string]mtglib.Event{
|
||||||
"start": mtglib.EventStart{
|
"start": mtglib.NewEventStart("connID", net.ParseIP("127.0.0.1")),
|
||||||
CreatedAt: time.Now(),
|
"connected-to-dc": mtglib.NewEventConnectedToDC("connID", net.ParseIP("127.1.0.1"), 2),
|
||||||
ConnID: "connID",
|
"domain-fronting": mtglib.NewEventDomainFronting("connID"),
|
||||||
RemoteIP: net.ParseIP("127.0.0.1"),
|
"traffic": mtglib.NewEventTraffic("connID", 1000, true),
|
||||||
},
|
"finish": mtglib.NewEventFinish("connID"),
|
||||||
"connected-to-dc": mtglib.EventConnectedToDC{
|
"concurrency-limited": mtglib.NewEventConcurrencyLimited(),
|
||||||
CreatedAt: time.Now(),
|
"ip-blacklisted": mtglib.NewEventIPBlocklisted(net.ParseIP("10.0.0.10")),
|
||||||
ConnID: "connID",
|
"replay-attack": mtglib.NewEventReplayAttack("connID"),
|
||||||
RemoteIP: net.ParseIP("127.1.0.1"),
|
|
||||||
DC: 2,
|
|
||||||
},
|
|
||||||
"domain-fronting": mtglib.EventDomainFronting{
|
|
||||||
CreatedAt: time.Now(),
|
|
||||||
ConnID: "connID",
|
|
||||||
},
|
|
||||||
"traffic": mtglib.EventTraffic{
|
|
||||||
CreatedAt: time.Now(),
|
|
||||||
ConnID: "connID",
|
|
||||||
Traffic: 1000,
|
|
||||||
IsRead: true,
|
|
||||||
},
|
|
||||||
"finish": mtglib.EventFinish{
|
|
||||||
CreatedAt: time.Now(),
|
|
||||||
ConnID: "connID",
|
|
||||||
},
|
|
||||||
"concurrency-limited": mtglib.EventConcurrencyLimited{
|
|
||||||
CreatedAt: time.Now(),
|
|
||||||
},
|
|
||||||
"ip-blacklisted": mtglib.EventIPBlocklisted{
|
|
||||||
RemoteIP: net.ParseIP("10.0.0.10"),
|
|
||||||
CreatedAt: time.Now(),
|
|
||||||
},
|
|
||||||
"replay-attack": mtglib.EventReplayAttack{
|
|
||||||
CreatedAt: time.Now(),
|
|
||||||
ConnID: "connID",
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
suite.ctx = context.Background()
|
suite.ctx = context.Background()
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-16
@@ -6,27 +6,21 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type connTraffic struct {
|
type connTraffic struct {
|
||||||
net.Conn
|
net.Conn
|
||||||
|
|
||||||
connID string
|
streamID string
|
||||||
stream EventStream
|
stream EventStream
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c connTraffic) Read(b []byte) (int, error) {
|
func (c connTraffic) Read(b []byte) (int, error) {
|
||||||
n, err := c.Conn.Read(b)
|
n, err := c.Conn.Read(b)
|
||||||
|
|
||||||
if n > 0 {
|
if n > 0 {
|
||||||
c.stream.Send(c.ctx, EventTraffic{
|
c.stream.Send(c.ctx, NewEventTraffic(c.streamID, uint(n), true))
|
||||||
CreatedAt: time.Now(),
|
|
||||||
ConnID: c.connID,
|
|
||||||
Traffic: uint(n),
|
|
||||||
IsRead: true,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return n, err // nolint: wrapcheck
|
return n, err // nolint: wrapcheck
|
||||||
@@ -36,12 +30,7 @@ func (c connTraffic) Write(b []byte) (int, error) {
|
|||||||
n, err := c.Conn.Write(b)
|
n, err := c.Conn.Write(b)
|
||||||
|
|
||||||
if n > 0 {
|
if n > 0 {
|
||||||
c.stream.Send(c.ctx, EventTraffic{
|
c.stream.Send(c.ctx, NewEventTraffic(c.streamID, uint(n), false))
|
||||||
CreatedAt: time.Now(),
|
|
||||||
ConnID: c.connID,
|
|
||||||
Traffic: uint(n),
|
|
||||||
IsRead: false,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return n, err // nolint: wrapcheck
|
return n, err // nolint: wrapcheck
|
||||||
|
|||||||
@@ -37,10 +37,10 @@ func (suite *ConnTrafficTestSuite) SetupTest() {
|
|||||||
suite.eventStreamMock = &EventStreamMock{}
|
suite.eventStreamMock = &EventStreamMock{}
|
||||||
suite.connMock = &testlib.NetConnMock{}
|
suite.connMock = &testlib.NetConnMock{}
|
||||||
suite.conn = connTraffic{
|
suite.conn = connTraffic{
|
||||||
Conn: suite.connMock,
|
Conn: suite.connMock,
|
||||||
connID: "CONNID",
|
streamID: "CONNID",
|
||||||
ctx: context.Background(),
|
ctx: context.Background(),
|
||||||
stream: suite.eventStreamMock,
|
stream: suite.eventStreamMock,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+99
-76
@@ -5,110 +5,133 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type eventBase struct {
|
||||||
|
streamID string
|
||||||
|
timestamp time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e eventBase) StreamID() string {
|
||||||
|
return e.streamID
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e eventBase) Timestamp() time.Time {
|
||||||
|
return e.timestamp
|
||||||
|
}
|
||||||
|
|
||||||
type EventStart struct {
|
type EventStart struct {
|
||||||
CreatedAt time.Time
|
eventBase
|
||||||
ConnID string
|
|
||||||
RemoteIP net.IP
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e EventStart) StreamID() string {
|
RemoteIP net.IP
|
||||||
return e.ConnID
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e EventStart) Timestamp() time.Time {
|
|
||||||
return e.CreatedAt
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type EventConnectedToDC struct {
|
type EventConnectedToDC struct {
|
||||||
CreatedAt time.Time
|
eventBase
|
||||||
ConnID string
|
|
||||||
RemoteIP net.IP
|
|
||||||
DC int
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e EventConnectedToDC) StreamID() string {
|
RemoteIP net.IP
|
||||||
return e.ConnID
|
DC int
|
||||||
}
|
|
||||||
|
|
||||||
func (e EventConnectedToDC) Timestamp() time.Time {
|
|
||||||
return e.CreatedAt
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type EventTraffic struct {
|
type EventTraffic struct {
|
||||||
CreatedAt time.Time
|
eventBase
|
||||||
ConnID string
|
|
||||||
Traffic uint
|
|
||||||
IsRead bool
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e EventTraffic) StreamID() string {
|
Traffic uint
|
||||||
return e.ConnID
|
IsRead bool
|
||||||
}
|
|
||||||
|
|
||||||
func (e EventTraffic) Timestamp() time.Time {
|
|
||||||
return e.CreatedAt
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type EventFinish struct {
|
type EventFinish struct {
|
||||||
CreatedAt time.Time
|
eventBase
|
||||||
ConnID string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e EventFinish) StreamID() string {
|
|
||||||
return e.ConnID
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e EventFinish) Timestamp() time.Time {
|
|
||||||
return e.CreatedAt
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type EventDomainFronting struct {
|
type EventDomainFronting struct {
|
||||||
CreatedAt time.Time
|
eventBase
|
||||||
ConnID string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e EventDomainFronting) StreamID() string {
|
|
||||||
return e.ConnID
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e EventDomainFronting) Timestamp() time.Time {
|
|
||||||
return e.CreatedAt
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type EventConcurrencyLimited struct {
|
type EventConcurrencyLimited struct {
|
||||||
CreatedAt time.Time
|
eventBase
|
||||||
}
|
|
||||||
|
|
||||||
func (e EventConcurrencyLimited) StreamID() string {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e EventConcurrencyLimited) Timestamp() time.Time {
|
|
||||||
return e.CreatedAt
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type EventIPBlocklisted struct {
|
type EventIPBlocklisted struct {
|
||||||
CreatedAt time.Time
|
eventBase
|
||||||
RemoteIP net.IP
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e EventIPBlocklisted) StreamID() string {
|
RemoteIP net.IP
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e EventIPBlocklisted) Timestamp() time.Time {
|
|
||||||
return e.CreatedAt
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type EventReplayAttack struct {
|
type EventReplayAttack struct {
|
||||||
CreatedAt time.Time
|
eventBase
|
||||||
ConnID string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e EventReplayAttack) StreamID() string {
|
func NewEventStart(streamID string, remoteIP net.IP) EventStart {
|
||||||
return e.ConnID
|
return EventStart{
|
||||||
|
eventBase: eventBase{
|
||||||
|
timestamp: time.Now(),
|
||||||
|
streamID: streamID,
|
||||||
|
},
|
||||||
|
RemoteIP: remoteIP,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e EventReplayAttack) Timestamp() time.Time {
|
func NewEventConnectedToDC(streamID string, remoteIP net.IP, dc int) EventConnectedToDC {
|
||||||
return e.CreatedAt
|
return EventConnectedToDC{
|
||||||
|
eventBase: eventBase{
|
||||||
|
timestamp: time.Now(),
|
||||||
|
streamID: streamID,
|
||||||
|
},
|
||||||
|
RemoteIP: remoteIP,
|
||||||
|
DC: dc,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewEventTraffic(streamID string, traffic uint, isRead bool) EventTraffic {
|
||||||
|
return EventTraffic{
|
||||||
|
eventBase: eventBase{
|
||||||
|
timestamp: time.Now(),
|
||||||
|
streamID: streamID,
|
||||||
|
},
|
||||||
|
Traffic: traffic,
|
||||||
|
IsRead: isRead,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewEventFinish(streamID string) EventFinish {
|
||||||
|
return EventFinish{
|
||||||
|
eventBase: eventBase{
|
||||||
|
timestamp: time.Now(),
|
||||||
|
streamID: streamID,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewEventDomainFronting(streamID string) EventDomainFronting {
|
||||||
|
return EventDomainFronting{
|
||||||
|
eventBase: eventBase{
|
||||||
|
timestamp: time.Now(),
|
||||||
|
streamID: streamID,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewEventConcurrencyLimited() EventConcurrencyLimited {
|
||||||
|
return EventConcurrencyLimited{
|
||||||
|
eventBase: eventBase{
|
||||||
|
timestamp: time.Now(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewEventIPBlocklisted(remoteIP net.IP) EventIPBlocklisted {
|
||||||
|
return EventIPBlocklisted{
|
||||||
|
eventBase: eventBase{
|
||||||
|
timestamp: time.Now(),
|
||||||
|
},
|
||||||
|
RemoteIP: remoteIP,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewEventReplayAttack(streamID string) EventReplayAttack {
|
||||||
|
return EventReplayAttack{
|
||||||
|
eventBase: eventBase{
|
||||||
|
timestamp: time.Now(),
|
||||||
|
streamID: streamID,
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-36
@@ -14,84 +14,56 @@ type EventsTestSuite struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (suite *EventsTestSuite) TestEventStart() {
|
func (suite *EventsTestSuite) TestEventStart() {
|
||||||
evt := mtglib.EventStart{
|
evt := mtglib.NewEventStart("CONNID", net.ParseIP("10.0.0.10"))
|
||||||
CreatedAt: time.Now(),
|
|
||||||
ConnID: "CONNID",
|
|
||||||
RemoteIP: net.ParseIP("10.0.0.10"),
|
|
||||||
}
|
|
||||||
|
|
||||||
suite.Equal("CONNID", evt.StreamID())
|
suite.Equal("CONNID", evt.StreamID())
|
||||||
suite.WithinDuration(time.Now(), evt.Timestamp(), 10*time.Millisecond)
|
suite.WithinDuration(time.Now(), evt.Timestamp(), 10*time.Millisecond)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *EventsTestSuite) TestEventFinish() {
|
func (suite *EventsTestSuite) TestEventFinish() {
|
||||||
evt := mtglib.EventFinish{
|
evt := mtglib.NewEventFinish("CONNID")
|
||||||
CreatedAt: time.Now(),
|
|
||||||
ConnID: "CONNID",
|
|
||||||
}
|
|
||||||
|
|
||||||
suite.Equal("CONNID", evt.StreamID())
|
suite.Equal("CONNID", evt.StreamID())
|
||||||
suite.WithinDuration(time.Now(), evt.Timestamp(), 10*time.Millisecond)
|
suite.WithinDuration(time.Now(), evt.Timestamp(), 10*time.Millisecond)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *EventsTestSuite) TestEventConnectedToDC() {
|
func (suite *EventsTestSuite) TestEventConnectedToDC() {
|
||||||
evt := mtglib.EventConnectedToDC{
|
evt := mtglib.NewEventConnectedToDC("CONNID", net.ParseIP("10.0.0.10"), 3)
|
||||||
CreatedAt: time.Now(),
|
|
||||||
ConnID: "CONNID",
|
|
||||||
RemoteIP: net.ParseIP("10.0.0.10"),
|
|
||||||
DC: 3,
|
|
||||||
}
|
|
||||||
|
|
||||||
suite.Equal("CONNID", evt.StreamID())
|
suite.Equal("CONNID", evt.StreamID())
|
||||||
suite.WithinDuration(time.Now(), evt.Timestamp(), 10*time.Millisecond)
|
suite.WithinDuration(time.Now(), evt.Timestamp(), 10*time.Millisecond)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *EventsTestSuite) TestEventTraffic() {
|
func (suite *EventsTestSuite) TestEventTraffic() {
|
||||||
evt := mtglib.EventTraffic{
|
evt := mtglib.NewEventTraffic("CONNID", 1000, true)
|
||||||
CreatedAt: time.Now(),
|
|
||||||
ConnID: "CONNID",
|
|
||||||
Traffic: 3,
|
|
||||||
IsRead: true,
|
|
||||||
}
|
|
||||||
|
|
||||||
suite.Equal("CONNID", evt.StreamID())
|
suite.Equal("CONNID", evt.StreamID())
|
||||||
suite.WithinDuration(time.Now(), evt.Timestamp(), 10*time.Millisecond)
|
suite.WithinDuration(time.Now(), evt.Timestamp(), 10*time.Millisecond)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *EventsTestSuite) TestEventDomainFronting() {
|
func (suite *EventsTestSuite) TestEventDomainFronting() {
|
||||||
evt := mtglib.EventDomainFronting{
|
evt := mtglib.NewEventDomainFronting("CONNID")
|
||||||
CreatedAt: time.Now(),
|
|
||||||
ConnID: "CONNID",
|
|
||||||
}
|
|
||||||
|
|
||||||
suite.Equal("CONNID", evt.StreamID())
|
suite.Equal("CONNID", evt.StreamID())
|
||||||
suite.WithinDuration(time.Now(), evt.Timestamp(), 10*time.Millisecond)
|
suite.WithinDuration(time.Now(), evt.Timestamp(), 10*time.Millisecond)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *EventsTestSuite) TestEventConcurrencyLimited() {
|
func (suite *EventsTestSuite) TestEventConcurrencyLimited() {
|
||||||
evt := mtglib.EventConcurrencyLimited{
|
evt := mtglib.NewEventConcurrencyLimited()
|
||||||
CreatedAt: time.Now(),
|
|
||||||
}
|
|
||||||
|
|
||||||
suite.Empty(evt.StreamID())
|
suite.Empty(evt.StreamID())
|
||||||
suite.WithinDuration(time.Now(), evt.Timestamp(), 10*time.Millisecond)
|
suite.WithinDuration(time.Now(), evt.Timestamp(), 10*time.Millisecond)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *EventsTestSuite) TestEventIPBlocklisted() {
|
func (suite *EventsTestSuite) TestEventIPBlocklisted() {
|
||||||
evt := mtglib.EventIPBlocklisted{
|
evt := mtglib.NewEventIPBlocklisted(net.ParseIP("10.0.0.10"))
|
||||||
CreatedAt: time.Now(),
|
|
||||||
RemoteIP: net.ParseIP("10.0.0.10"),
|
|
||||||
}
|
|
||||||
|
|
||||||
suite.Empty(evt.StreamID())
|
suite.Empty(evt.StreamID())
|
||||||
suite.WithinDuration(time.Now(), evt.Timestamp(), 10*time.Millisecond)
|
suite.WithinDuration(time.Now(), evt.Timestamp(), 10*time.Millisecond)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *EventsTestSuite) TestEventReplayAttack() {
|
func (suite *EventsTestSuite) TestEventReplayAttack() {
|
||||||
evt := mtglib.EventReplayAttack{
|
evt := mtglib.NewEventReplayAttack("CONNID")
|
||||||
CreatedAt: time.Now(),
|
|
||||||
ConnID: "CONNID",
|
|
||||||
}
|
|
||||||
|
|
||||||
suite.Equal("CONNID", evt.StreamID())
|
suite.Equal("CONNID", evt.StreamID())
|
||||||
suite.WithinDuration(time.Now(), evt.Timestamp(), 10*time.Millisecond)
|
suite.WithinDuration(time.Now(), evt.Timestamp(), 10*time.Millisecond)
|
||||||
|
|||||||
+71
-11
@@ -9,22 +9,66 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ErrSecretEmpty = errors.New("secret is empty")
|
// ErrSecretEmpty is returned if you are trying to create a proxy
|
||||||
ErrSecretInvalid = errors.New("secret is invalid")
|
// but do not provide a secret.
|
||||||
ErrNetworkIsNotDefined = errors.New("network is not defined")
|
ErrSecretEmpty = errors.New("secret is empty")
|
||||||
ErrAntiReplayCacheIsNotDefined = errors.New("anti-replay cache is not defined")
|
|
||||||
|
// ErrSecretInvalid is returned if you are trying to create a proxy
|
||||||
|
// but secret value is invalid (no host or payload are zeroes).
|
||||||
|
ErrSecretInvalid = errors.New("secret is invalid")
|
||||||
|
|
||||||
|
// ErrNetworkIsNotDefined is returned if you are trying to create a
|
||||||
|
// proxy but network value is undefined.
|
||||||
|
ErrNetworkIsNotDefined = errors.New("network is not defined")
|
||||||
|
|
||||||
|
// ErrAntiReplayCacheIsNotDefined is returned if you are trying to
|
||||||
|
// create a proxy but anti replay cache value is undefined.
|
||||||
|
ErrAntiReplayCacheIsNotDefined = errors.New("anti-replay cache is not defined")
|
||||||
|
|
||||||
|
// ErrTimeAttackDetectorIsNotDefined is returned if you are trying to
|
||||||
|
// create a proxy but time attack detector is not defined.
|
||||||
ErrTimeAttackDetectorIsNotDefined = errors.New("time attack detector is not defined")
|
ErrTimeAttackDetectorIsNotDefined = errors.New("time attack detector is not defined")
|
||||||
ErrIPBlocklistIsNotDefined = errors.New("ip blocklist is not defined")
|
|
||||||
ErrEventStreamIsNotDefined = errors.New("event stream is not defined")
|
// ErrIPBlocklistIsNotDefined is returned if you are trying to
|
||||||
ErrLoggerIsNotDefined = errors.New("logger is not defined")
|
// create a proxy but ip blocklist instance is not defined.
|
||||||
|
ErrIPBlocklistIsNotDefined = errors.New("ip blocklist is not defined")
|
||||||
|
|
||||||
|
// ErrEventStreamIsNotDefined is returned if you are trying to create a
|
||||||
|
// proxy but event stream instance is not defined.
|
||||||
|
ErrEventStreamIsNotDefined = errors.New("event stream is not defined")
|
||||||
|
|
||||||
|
// ErrLoggerIsNotDefined is returned if you are trying to
|
||||||
|
// create a proxy but logger is not defined.
|
||||||
|
ErrLoggerIsNotDefined = errors.New("logger is not defined")
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
DefaultConcurrency = 4096
|
// DefaultConcurrency is a default max count of simultaneously
|
||||||
DefaultBufferSize = 16 * 1024 // 16 kib
|
// connected clients.
|
||||||
|
DefaultConcurrency = 4096
|
||||||
|
|
||||||
|
// DefaultBufferSize is a default size of a copy buffer.
|
||||||
|
DefaultBufferSize = 16 * 1024 // 16 kib
|
||||||
|
|
||||||
|
// DefaultDomainFrontingPort is a default port (HTTPS) to connect to in
|
||||||
|
// case of probe-resistance activity.
|
||||||
DefaultDomainFrontingPort = 443
|
DefaultDomainFrontingPort = 443
|
||||||
DefaultIdleTimeout = time.Minute
|
|
||||||
DefaultPreferIP = "prefer-ipv6"
|
// DefaultIdleTimeout is a default timeout for closing a connection
|
||||||
|
// in case of idling.
|
||||||
|
DefaultIdleTimeout = time.Minute
|
||||||
|
|
||||||
|
// DefaultPreferIP is a default value for Telegram IP connectivity
|
||||||
|
// preference.
|
||||||
|
DefaultPreferIP = "prefer-ipv6"
|
||||||
|
|
||||||
|
// SecretKeyLength defines a length of the secret bytes used
|
||||||
|
// by Telegram and a proxy.
|
||||||
|
SecretKeyLength = 16
|
||||||
|
|
||||||
|
// ConnectionIDBytesLength defines a count of random bytes
|
||||||
|
// used to generate a stream/connection ids.
|
||||||
|
ConnectionIDBytesLength = 16
|
||||||
)
|
)
|
||||||
|
|
||||||
// Network defines a knowledge how to work with a network. It may sound
|
// Network defines a knowledge how to work with a network. It may sound
|
||||||
@@ -105,8 +149,24 @@ type IPBlocklist interface {
|
|||||||
Contains(net.IP) bool
|
Contains(net.IP) bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Event is a data structure which is populated during mtg request
|
||||||
|
// processing lifecycle. Each request popluates many events:
|
||||||
|
//
|
||||||
|
// 1. Client connected
|
||||||
|
//
|
||||||
|
// 2. Request is finished
|
||||||
|
//
|
||||||
|
// 3. Connection to Telegram server is established
|
||||||
|
//
|
||||||
|
// and so on. All these events are data structures but all of them
|
||||||
|
// must conform the same interface.
|
||||||
type Event interface {
|
type Event interface {
|
||||||
|
// StreamID returns an identifier of the stream, connection,
|
||||||
|
// request, you name it. All events within the same stream returns
|
||||||
|
// the same stream id.
|
||||||
StreamID() string
|
StreamID() string
|
||||||
|
|
||||||
|
// Timestamp returns a timestamp when this event was generated.
|
||||||
Timestamp() time.Time
|
Timestamp() time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+16
-39
@@ -53,18 +53,11 @@ func (p *Proxy) ServeConn(conn net.Conn) {
|
|||||||
ctx.Close()
|
ctx.Close()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
p.eventStream.Send(ctx, EventStart{
|
p.eventStream.Send(ctx, NewEventStart(ctx.streamID, ctx.ClientIP()))
|
||||||
CreatedAt: time.Now(),
|
|
||||||
ConnID: ctx.connID,
|
|
||||||
RemoteIP: ctx.ClientIP(),
|
|
||||||
})
|
|
||||||
ctx.logger.Info("Stream has been started")
|
ctx.logger.Info("Stream has been started")
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
p.eventStream.Send(ctx, EventFinish{
|
p.eventStream.Send(ctx, NewEventFinish(ctx.streamID))
|
||||||
CreatedAt: time.Now(),
|
|
||||||
ConnID: ctx.connID,
|
|
||||||
})
|
|
||||||
ctx.logger.Info("Stream has been finished")
|
ctx.logger.Info("Stream has been finished")
|
||||||
}()
|
}()
|
||||||
|
|
||||||
@@ -109,10 +102,7 @@ func (p *Proxy) Serve(listener net.Listener) error {
|
|||||||
if p.ipBlocklist.Contains(ipAddr) {
|
if p.ipBlocklist.Contains(ipAddr) {
|
||||||
conn.Close()
|
conn.Close()
|
||||||
logger.Info("ip was blacklisted")
|
logger.Info("ip was blacklisted")
|
||||||
p.eventStream.Send(p.ctx, EventIPBlocklisted{
|
p.eventStream.Send(p.ctx, NewEventIPBlocklisted(ipAddr))
|
||||||
CreatedAt: time.Now(),
|
|
||||||
RemoteIP: ipAddr,
|
|
||||||
})
|
|
||||||
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -125,9 +115,7 @@ func (p *Proxy) Serve(listener net.Listener) error {
|
|||||||
return nil
|
return nil
|
||||||
case errors.Is(err, ants.ErrPoolOverload):
|
case errors.Is(err, ants.ErrPoolOverload):
|
||||||
logger.Info("connection was concurrency limited")
|
logger.Info("connection was concurrency limited")
|
||||||
p.eventStream.Send(p.ctx, EventConcurrencyLimited{
|
p.eventStream.Send(p.ctx, NewEventConcurrencyLimited())
|
||||||
CreatedAt: time.Now(),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
select {
|
select {
|
||||||
@@ -181,10 +169,7 @@ func (p *Proxy) doFakeTLSHandshake(ctx *streamContext) bool {
|
|||||||
|
|
||||||
if p.antiReplayCache.SeenBefore(hello.SessionID) {
|
if p.antiReplayCache.SeenBefore(hello.SessionID) {
|
||||||
p.logger.Warning("replay attack has been detected!")
|
p.logger.Warning("replay attack has been detected!")
|
||||||
p.eventStream.Send(p.ctx, EventReplayAttack{
|
p.eventStream.Send(p.ctx, NewEventReplayAttack(ctx.streamID))
|
||||||
CreatedAt: time.Now(),
|
|
||||||
ConnID: ctx.connID,
|
|
||||||
})
|
|
||||||
p.doDomainFronting(ctx, rewind)
|
p.doDomainFronting(ctx, rewind)
|
||||||
|
|
||||||
return false
|
return false
|
||||||
@@ -235,31 +220,23 @@ func (p *Proxy) doTelegramCall(ctx *streamContext) error {
|
|||||||
|
|
||||||
ctx.telegramConn = obfuscated2.Conn{
|
ctx.telegramConn = obfuscated2.Conn{
|
||||||
Conn: connTraffic{
|
Conn: connTraffic{
|
||||||
Conn: conn,
|
Conn: conn,
|
||||||
connID: ctx.connID,
|
streamID: ctx.streamID,
|
||||||
stream: p.eventStream,
|
stream: p.eventStream,
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
},
|
},
|
||||||
Encryptor: encryptor,
|
Encryptor: encryptor,
|
||||||
Decryptor: decryptor,
|
Decryptor: decryptor,
|
||||||
}
|
}
|
||||||
|
|
||||||
p.eventStream.Send(ctx, EventConnectedToDC{
|
p.eventStream.Send(ctx,
|
||||||
CreatedAt: time.Now(),
|
NewEventConnectedToDC(ctx.streamID, conn.RemoteAddr().(*net.TCPAddr).IP, ctx.dc))
|
||||||
ConnID: ctx.connID,
|
|
||||||
RemoteIP: conn.RemoteAddr().(*net.TCPAddr).IP,
|
|
||||||
DC: ctx.dc,
|
|
||||||
})
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Proxy) doDomainFronting(ctx *streamContext, conn *connRewind) {
|
func (p *Proxy) doDomainFronting(ctx *streamContext, conn *connRewind) {
|
||||||
p.eventStream.Send(p.ctx, EventDomainFronting{
|
p.eventStream.Send(p.ctx, NewEventDomainFronting(ctx.streamID))
|
||||||
CreatedAt: time.Now(),
|
|
||||||
ConnID: ctx.connID,
|
|
||||||
})
|
|
||||||
|
|
||||||
conn.Rewind()
|
conn.Rewind()
|
||||||
|
|
||||||
frontConn, err := p.network.DialContext(ctx, "tcp", p.DomainFrontingAddress())
|
frontConn, err := p.network.DialContext(ctx, "tcp", p.DomainFrontingAddress())
|
||||||
@@ -270,10 +247,10 @@ func (p *Proxy) doDomainFronting(ctx *streamContext, conn *connRewind) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
frontConn = connTraffic{
|
frontConn = connTraffic{
|
||||||
Conn: frontConn,
|
Conn: frontConn,
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
connID: ctx.connID,
|
streamID: ctx.streamID,
|
||||||
stream: p.eventStream,
|
stream: p.eventStream,
|
||||||
}
|
}
|
||||||
|
|
||||||
rel := relay.AcquireRelay(ctx,
|
rel := relay.AcquireRelay(ctx,
|
||||||
|
|||||||
+1
-5
@@ -7,11 +7,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const secretFakeTLSFirstByte byte = 0xee
|
||||||
SecretKeyLength = 16
|
|
||||||
|
|
||||||
secretFakeTLSFirstByte byte = 0xee
|
|
||||||
)
|
|
||||||
|
|
||||||
var secretEmptyKey [SecretKeyLength]byte
|
var secretEmptyKey [SecretKeyLength]byte
|
||||||
|
|
||||||
|
|||||||
@@ -8,14 +8,12 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
const ConnectionIDBytesLength = 16
|
|
||||||
|
|
||||||
type streamContext struct {
|
type streamContext struct {
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
ctxCancel context.CancelFunc
|
ctxCancel context.CancelFunc
|
||||||
clientConn net.Conn
|
clientConn net.Conn
|
||||||
telegramConn net.Conn
|
telegramConn net.Conn
|
||||||
connID string
|
streamID string
|
||||||
dc int
|
dc int
|
||||||
logger Logger
|
logger Logger
|
||||||
}
|
}
|
||||||
@@ -64,10 +62,10 @@ func newStreamContext(ctx context.Context, logger Logger, clientConn net.Conn) *
|
|||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
ctxCancel: cancel,
|
ctxCancel: cancel,
|
||||||
clientConn: clientConn,
|
clientConn: clientConn,
|
||||||
connID: base64.RawURLEncoding.EncodeToString(connIDBytes),
|
streamID: base64.RawURLEncoding.EncodeToString(connIDBytes),
|
||||||
}
|
}
|
||||||
streamCtx.logger = logger.
|
streamCtx.logger = logger.
|
||||||
BindStr("stream-id", streamCtx.connID).
|
BindStr("stream-id", streamCtx.streamID).
|
||||||
BindStr("client-ip", streamCtx.ClientIP().String())
|
BindStr("client-ip", streamCtx.ClientIP().String())
|
||||||
|
|
||||||
return streamCtx
|
return streamCtx
|
||||||
|
|||||||
+21
-63
@@ -55,57 +55,39 @@ func (suite *PrometheusTestSuite) TearDownTest() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (suite *PrometheusTestSuite) TestTelegramPath() {
|
func (suite *PrometheusTestSuite) TestTelegramPath() {
|
||||||
suite.prometheus.EventStart(mtglib.EventStart{
|
suite.prometheus.EventStart(
|
||||||
CreatedAt: time.Now(),
|
mtglib.NewEventStart("connID", net.ParseIP("10.0.0.10")))
|
||||||
ConnID: "connID",
|
|
||||||
RemoteIP: net.ParseIP("10.0.0.10"),
|
|
||||||
})
|
|
||||||
time.Sleep(100 * time.Millisecond)
|
time.Sleep(100 * time.Millisecond)
|
||||||
|
|
||||||
data, err := suite.Get()
|
data, err := suite.Get()
|
||||||
suite.NoError(err)
|
suite.NoError(err)
|
||||||
suite.Contains(data, `mtg_client_connections{ip_family="ipv4"} 1`)
|
suite.Contains(data, `mtg_client_connections{ip_family="ipv4"} 1`)
|
||||||
|
|
||||||
suite.prometheus.EventConnectedToDC(mtglib.EventConnectedToDC{
|
suite.prometheus.EventConnectedToDC(
|
||||||
CreatedAt: time.Now(),
|
mtglib.NewEventConnectedToDC("connID", net.ParseIP("10.0.0.1"), 4))
|
||||||
ConnID: "connID",
|
|
||||||
RemoteIP: net.ParseIP("10.0.0.1"),
|
|
||||||
DC: 4,
|
|
||||||
})
|
|
||||||
time.Sleep(100 * time.Millisecond)
|
time.Sleep(100 * time.Millisecond)
|
||||||
|
|
||||||
data, err = suite.Get()
|
data, err = suite.Get()
|
||||||
suite.NoError(err)
|
suite.NoError(err)
|
||||||
suite.Contains(data, `mtg_telegram_connections{dc="4",telegram_ip="10.0.0.1"} 1`)
|
suite.Contains(data, `mtg_telegram_connections{dc="4",telegram_ip="10.0.0.1"} 1`)
|
||||||
|
|
||||||
suite.prometheus.EventTraffic(mtglib.EventTraffic{
|
suite.prometheus.EventTraffic(
|
||||||
CreatedAt: time.Now(),
|
mtglib.NewEventTraffic("connID", 200, true))
|
||||||
ConnID: "connID",
|
|
||||||
Traffic: 200,
|
|
||||||
IsRead: true,
|
|
||||||
})
|
|
||||||
time.Sleep(100 * time.Millisecond)
|
time.Sleep(100 * time.Millisecond)
|
||||||
|
|
||||||
data, err = suite.Get()
|
data, err = suite.Get()
|
||||||
suite.NoError(err)
|
suite.NoError(err)
|
||||||
suite.Contains(data, `mtg_telegram_traffic{dc="4",direction="to_client",telegram_ip="10.0.0.1"} 200`)
|
suite.Contains(data, `mtg_telegram_traffic{dc="4",direction="to_client",telegram_ip="10.0.0.1"} 200`)
|
||||||
|
|
||||||
suite.prometheus.EventTraffic(mtglib.EventTraffic{
|
suite.prometheus.EventTraffic(
|
||||||
CreatedAt: time.Now(),
|
mtglib.NewEventTraffic("connID", 100, false))
|
||||||
ConnID: "connID",
|
|
||||||
Traffic: 100,
|
|
||||||
IsRead: false,
|
|
||||||
})
|
|
||||||
time.Sleep(100 * time.Millisecond)
|
time.Sleep(100 * time.Millisecond)
|
||||||
|
|
||||||
data, err = suite.Get()
|
data, err = suite.Get()
|
||||||
suite.NoError(err)
|
suite.NoError(err)
|
||||||
suite.Contains(data, `mtg_telegram_traffic{dc="4",direction="from_client",telegram_ip="10.0.0.1"} 100`)
|
suite.Contains(data, `mtg_telegram_traffic{dc="4",direction="from_client",telegram_ip="10.0.0.1"} 100`)
|
||||||
|
|
||||||
suite.prometheus.EventFinish(mtglib.EventFinish{
|
suite.prometheus.EventFinish(mtglib.NewEventFinish("connID"))
|
||||||
CreatedAt: time.Now(),
|
|
||||||
ConnID: "connID",
|
|
||||||
})
|
|
||||||
time.Sleep(100 * time.Millisecond)
|
time.Sleep(100 * time.Millisecond)
|
||||||
|
|
||||||
data, err = suite.Get()
|
data, err = suite.Get()
|
||||||
@@ -115,21 +97,15 @@ func (suite *PrometheusTestSuite) TestTelegramPath() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (suite *PrometheusTestSuite) TestDomainFrontingPath() {
|
func (suite *PrometheusTestSuite) TestDomainFrontingPath() {
|
||||||
suite.prometheus.EventStart(mtglib.EventStart{
|
suite.prometheus.EventStart(
|
||||||
CreatedAt: time.Now(),
|
mtglib.NewEventStart("connID", net.ParseIP("10.0.0.10")))
|
||||||
ConnID: "connID",
|
|
||||||
RemoteIP: net.ParseIP("10.0.0.10"),
|
|
||||||
})
|
|
||||||
time.Sleep(100 * time.Millisecond)
|
time.Sleep(100 * time.Millisecond)
|
||||||
|
|
||||||
data, err := suite.Get()
|
data, err := suite.Get()
|
||||||
suite.NoError(err)
|
suite.NoError(err)
|
||||||
suite.Contains(data, `mtg_client_connections{ip_family="ipv4"} 1`)
|
suite.Contains(data, `mtg_client_connections{ip_family="ipv4"} 1`)
|
||||||
|
|
||||||
suite.prometheus.EventDomainFronting(mtglib.EventDomainFronting{
|
suite.prometheus.EventDomainFronting(mtglib.NewEventDomainFronting("connID"))
|
||||||
CreatedAt: time.Now(),
|
|
||||||
ConnID: "connID",
|
|
||||||
})
|
|
||||||
time.Sleep(100 * time.Millisecond)
|
time.Sleep(100 * time.Millisecond)
|
||||||
|
|
||||||
data, err = suite.Get()
|
data, err = suite.Get()
|
||||||
@@ -137,34 +113,23 @@ func (suite *PrometheusTestSuite) TestDomainFrontingPath() {
|
|||||||
suite.Contains(data, `mtg_domain_fronting 1`)
|
suite.Contains(data, `mtg_domain_fronting 1`)
|
||||||
suite.Contains(data, `mtg_domain_fronting_connections{ip_family="ipv4"} 1`)
|
suite.Contains(data, `mtg_domain_fronting_connections{ip_family="ipv4"} 1`)
|
||||||
|
|
||||||
suite.prometheus.EventTraffic(mtglib.EventTraffic{
|
suite.prometheus.EventTraffic(
|
||||||
CreatedAt: time.Now(),
|
mtglib.NewEventTraffic("connID", 200, true))
|
||||||
ConnID: "connID",
|
|
||||||
Traffic: 200,
|
|
||||||
IsRead: true,
|
|
||||||
})
|
|
||||||
time.Sleep(100 * time.Millisecond)
|
time.Sleep(100 * time.Millisecond)
|
||||||
|
|
||||||
data, err = suite.Get()
|
data, err = suite.Get()
|
||||||
suite.NoError(err)
|
suite.NoError(err)
|
||||||
suite.Contains(data, `mtg_domain_fronting_traffic{direction="to_client"} 200`)
|
suite.Contains(data, `mtg_domain_fronting_traffic{direction="to_client"} 200`)
|
||||||
|
|
||||||
suite.prometheus.EventTraffic(mtglib.EventTraffic{
|
suite.prometheus.EventTraffic(
|
||||||
CreatedAt: time.Now(),
|
mtglib.NewEventTraffic("connID", 100, false))
|
||||||
ConnID: "connID",
|
|
||||||
Traffic: 100,
|
|
||||||
IsRead: false,
|
|
||||||
})
|
|
||||||
time.Sleep(100 * time.Millisecond)
|
time.Sleep(100 * time.Millisecond)
|
||||||
|
|
||||||
data, err = suite.Get()
|
data, err = suite.Get()
|
||||||
suite.NoError(err)
|
suite.NoError(err)
|
||||||
suite.Contains(data, `mtg_domain_fronting_traffic{direction="from_client"} 100`)
|
suite.Contains(data, `mtg_domain_fronting_traffic{direction="from_client"} 100`)
|
||||||
|
|
||||||
suite.prometheus.EventFinish(mtglib.EventFinish{
|
suite.prometheus.EventFinish(mtglib.NewEventFinish("connID"))
|
||||||
CreatedAt: time.Now(),
|
|
||||||
ConnID: "connID",
|
|
||||||
})
|
|
||||||
time.Sleep(100 * time.Millisecond)
|
time.Sleep(100 * time.Millisecond)
|
||||||
|
|
||||||
data, err = suite.Get()
|
data, err = suite.Get()
|
||||||
@@ -174,9 +139,7 @@ func (suite *PrometheusTestSuite) TestDomainFrontingPath() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (suite *PrometheusTestSuite) TestEventConcurrencyLimited() {
|
func (suite *PrometheusTestSuite) TestEventConcurrencyLimited() {
|
||||||
suite.prometheus.EventConcurrencyLimited(mtglib.EventConcurrencyLimited{
|
suite.prometheus.EventConcurrencyLimited(mtglib.NewEventConcurrencyLimited())
|
||||||
CreatedAt: time.Now(),
|
|
||||||
})
|
|
||||||
|
|
||||||
time.Sleep(100 * time.Millisecond)
|
time.Sleep(100 * time.Millisecond)
|
||||||
|
|
||||||
@@ -186,10 +149,8 @@ func (suite *PrometheusTestSuite) TestEventConcurrencyLimited() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (suite *PrometheusTestSuite) TestEventIPBlocklisted() {
|
func (suite *PrometheusTestSuite) TestEventIPBlocklisted() {
|
||||||
suite.prometheus.EventIPBlocklisted(mtglib.EventIPBlocklisted{
|
suite.prometheus.EventIPBlocklisted(
|
||||||
CreatedAt: time.Now(),
|
mtglib.NewEventIPBlocklisted(net.ParseIP("2001:db8::68")))
|
||||||
RemoteIP: net.ParseIP("2001:db8::68"),
|
|
||||||
})
|
|
||||||
|
|
||||||
time.Sleep(100 * time.Millisecond)
|
time.Sleep(100 * time.Millisecond)
|
||||||
|
|
||||||
@@ -199,10 +160,7 @@ func (suite *PrometheusTestSuite) TestEventIPBlocklisted() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (suite *PrometheusTestSuite) TestEventReplayAttack() {
|
func (suite *PrometheusTestSuite) TestEventReplayAttack() {
|
||||||
suite.prometheus.EventReplayAttack(mtglib.EventReplayAttack{
|
suite.prometheus.EventReplayAttack(mtglib.NewEventReplayAttack("connID"))
|
||||||
CreatedAt: time.Now(),
|
|
||||||
ConnID: "connID",
|
|
||||||
})
|
|
||||||
|
|
||||||
time.Sleep(100 * time.Millisecond)
|
time.Sleep(100 * time.Millisecond)
|
||||||
|
|
||||||
|
|||||||
+1
-6
@@ -4,7 +4,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/9seconds/mtg/v2/events"
|
"github.com/9seconds/mtg/v2/events"
|
||||||
"github.com/9seconds/mtg/v2/logger"
|
"github.com/9seconds/mtg/v2/logger"
|
||||||
@@ -123,14 +122,10 @@ func (s statsdProcessor) EventReplayAttack(_ mtglib.EventReplayAttack) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s statsdProcessor) Shutdown() {
|
func (s statsdProcessor) Shutdown() {
|
||||||
now := time.Now()
|
|
||||||
events := make([]mtglib.EventFinish, 0, len(s.streams))
|
events := make([]mtglib.EventFinish, 0, len(s.streams))
|
||||||
|
|
||||||
for k := range s.streams {
|
for k := range s.streams {
|
||||||
events = append(events, mtglib.EventFinish{
|
events = append(events, mtglib.NewEventFinish(k))
|
||||||
CreatedAt: now,
|
|
||||||
ConnID: k,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := range events {
|
for i := range events {
|
||||||
|
|||||||
+21
-63
@@ -105,48 +105,30 @@ func (suite *StatsdTestSuite) TearDownTest() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (suite *StatsdTestSuite) TestTelegramPath() {
|
func (suite *StatsdTestSuite) TestTelegramPath() {
|
||||||
suite.statsd.EventStart(mtglib.EventStart{
|
suite.statsd.EventStart(
|
||||||
CreatedAt: time.Now(),
|
mtglib.NewEventStart("connID", net.ParseIP("10.0.0.10")))
|
||||||
ConnID: "connID",
|
|
||||||
RemoteIP: net.ParseIP("10.0.0.10"),
|
|
||||||
})
|
|
||||||
time.Sleep(statsdSleepTime)
|
time.Sleep(statsdSleepTime)
|
||||||
suite.Equal("mtg.client_connections:+1|g|#ip_family:ipv4", suite.statsdServer.String())
|
suite.Equal("mtg.client_connections:+1|g|#ip_family:ipv4", suite.statsdServer.String())
|
||||||
|
|
||||||
suite.statsd.EventConnectedToDC(mtglib.EventConnectedToDC{
|
suite.statsd.EventConnectedToDC(
|
||||||
CreatedAt: time.Now(),
|
mtglib.NewEventConnectedToDC("connID", net.ParseIP("10.1.0.10"), 2))
|
||||||
ConnID: "connID",
|
|
||||||
RemoteIP: net.ParseIP("10.1.0.10"),
|
|
||||||
DC: 2,
|
|
||||||
})
|
|
||||||
time.Sleep(statsdSleepTime)
|
time.Sleep(statsdSleepTime)
|
||||||
suite.Contains(suite.statsdServer.String(),
|
suite.Contains(suite.statsdServer.String(),
|
||||||
"mtg.telegram_connections:+1|g|#telegram_ip:10.1.0.10,dc:2")
|
"mtg.telegram_connections:+1|g|#telegram_ip:10.1.0.10,dc:2")
|
||||||
|
|
||||||
suite.statsd.EventTraffic(mtglib.EventTraffic{
|
suite.statsd.EventTraffic(
|
||||||
CreatedAt: time.Now(),
|
mtglib.NewEventTraffic("connID", 30, true))
|
||||||
ConnID: "connID",
|
|
||||||
Traffic: 30,
|
|
||||||
IsRead: true,
|
|
||||||
})
|
|
||||||
time.Sleep(statsdSleepTime)
|
time.Sleep(statsdSleepTime)
|
||||||
suite.Contains(suite.statsdServer.String(),
|
suite.Contains(suite.statsdServer.String(),
|
||||||
"mtg.telegram_traffic:30|c|#telegram_ip:10.1.0.10,dc:2,direction:to_client")
|
"mtg.telegram_traffic:30|c|#telegram_ip:10.1.0.10,dc:2,direction:to_client")
|
||||||
|
|
||||||
suite.statsd.EventTraffic(mtglib.EventTraffic{
|
suite.statsd.EventTraffic(
|
||||||
CreatedAt: time.Now(),
|
mtglib.NewEventTraffic("connID", 90, false))
|
||||||
ConnID: "connID",
|
|
||||||
Traffic: 90,
|
|
||||||
IsRead: false,
|
|
||||||
})
|
|
||||||
time.Sleep(statsdSleepTime)
|
time.Sleep(statsdSleepTime)
|
||||||
suite.Contains(suite.statsdServer.String(),
|
suite.Contains(suite.statsdServer.String(),
|
||||||
"mtg.telegram_traffic:90|c|#telegram_ip:10.1.0.10,dc:2,direction:from_client")
|
"mtg.telegram_traffic:90|c|#telegram_ip:10.1.0.10,dc:2,direction:from_client")
|
||||||
|
|
||||||
suite.statsd.EventFinish(mtglib.EventFinish{
|
suite.statsd.EventFinish(mtglib.NewEventFinish("connID"))
|
||||||
CreatedAt: time.Now(),
|
|
||||||
ConnID: "connID",
|
|
||||||
})
|
|
||||||
time.Sleep(statsdSleepTime)
|
time.Sleep(statsdSleepTime)
|
||||||
suite.Contains(suite.statsdServer.String(),
|
suite.Contains(suite.statsdServer.String(),
|
||||||
"mtg.telegram_connections:-1|g|#telegram_ip:10.1.0.10,dc:2")
|
"mtg.telegram_connections:-1|g|#telegram_ip:10.1.0.10,dc:2")
|
||||||
@@ -158,47 +140,30 @@ func (suite *StatsdTestSuite) TestTelegramPath() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (suite *StatsdTestSuite) TestDomainFrontingPath() {
|
func (suite *StatsdTestSuite) TestDomainFrontingPath() {
|
||||||
suite.statsd.EventStart(mtglib.EventStart{
|
suite.statsd.EventStart(
|
||||||
CreatedAt: time.Now(),
|
mtglib.NewEventStart("connID", net.ParseIP("10.0.0.10")))
|
||||||
ConnID: "connID",
|
|
||||||
RemoteIP: net.ParseIP("10.0.0.10"),
|
|
||||||
})
|
|
||||||
time.Sleep(statsdSleepTime)
|
time.Sleep(statsdSleepTime)
|
||||||
suite.Equal("mtg.client_connections:+1|g|#ip_family:ipv4", suite.statsdServer.String())
|
suite.Equal("mtg.client_connections:+1|g|#ip_family:ipv4", suite.statsdServer.String())
|
||||||
|
|
||||||
suite.statsd.EventDomainFronting(mtglib.EventDomainFronting{
|
suite.statsd.EventDomainFronting(mtglib.NewEventDomainFronting("connID"))
|
||||||
CreatedAt: time.Now(),
|
|
||||||
ConnID: "connID",
|
|
||||||
})
|
|
||||||
time.Sleep(statsdSleepTime)
|
time.Sleep(statsdSleepTime)
|
||||||
suite.Contains(suite.statsdServer.String(), "mtg.domain_fronting:1|c")
|
suite.Contains(suite.statsdServer.String(), "mtg.domain_fronting:1|c")
|
||||||
suite.Contains(suite.statsdServer.String(),
|
suite.Contains(suite.statsdServer.String(),
|
||||||
`mtg.domain_fronting_connections:+1|g|#ip_family:ipv4`)
|
`mtg.domain_fronting_connections:+1|g|#ip_family:ipv4`)
|
||||||
|
|
||||||
suite.statsd.EventTraffic(mtglib.EventTraffic{
|
suite.statsd.EventTraffic(
|
||||||
CreatedAt: time.Now(),
|
mtglib.NewEventTraffic("connID", 30, true))
|
||||||
ConnID: "connID",
|
|
||||||
Traffic: 30,
|
|
||||||
IsRead: true,
|
|
||||||
})
|
|
||||||
time.Sleep(statsdSleepTime)
|
time.Sleep(statsdSleepTime)
|
||||||
suite.Contains(suite.statsdServer.String(),
|
suite.Contains(suite.statsdServer.String(),
|
||||||
`mtg.domain_fronting_traffic:30|c|#direction:to_client`)
|
`mtg.domain_fronting_traffic:30|c|#direction:to_client`)
|
||||||
|
|
||||||
suite.statsd.EventTraffic(mtglib.EventTraffic{
|
suite.statsd.EventTraffic(
|
||||||
CreatedAt: time.Now(),
|
mtglib.NewEventTraffic("connID", 90, false))
|
||||||
ConnID: "connID",
|
|
||||||
Traffic: 90,
|
|
||||||
IsRead: false,
|
|
||||||
})
|
|
||||||
time.Sleep(statsdSleepTime)
|
time.Sleep(statsdSleepTime)
|
||||||
suite.Contains(suite.statsdServer.String(),
|
suite.Contains(suite.statsdServer.String(),
|
||||||
`mtg.domain_fronting_traffic:90|c|#direction:from_client`)
|
`mtg.domain_fronting_traffic:90|c|#direction:from_client`)
|
||||||
|
|
||||||
suite.statsd.EventFinish(mtglib.EventFinish{
|
suite.statsd.EventFinish(mtglib.NewEventFinish("connID"))
|
||||||
CreatedAt: time.Now(),
|
|
||||||
ConnID: "connID",
|
|
||||||
})
|
|
||||||
time.Sleep(statsdSleepTime)
|
time.Sleep(statsdSleepTime)
|
||||||
suite.Contains(suite.statsdServer.String(),
|
suite.Contains(suite.statsdServer.String(),
|
||||||
"mtg.domain_fronting_connections:-1|g|#ip_family:ipv4")
|
"mtg.domain_fronting_connections:-1|g|#ip_family:ipv4")
|
||||||
@@ -210,29 +175,22 @@ func (suite *StatsdTestSuite) TestDomainFrontingPath() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (suite *StatsdTestSuite) TestEventConcurrencyLimited() {
|
func (suite *StatsdTestSuite) TestEventConcurrencyLimited() {
|
||||||
suite.statsd.EventConcurrencyLimited(mtglib.EventConcurrencyLimited{
|
suite.statsd.EventConcurrencyLimited(mtglib.NewEventConcurrencyLimited())
|
||||||
CreatedAt: time.Now(),
|
|
||||||
})
|
|
||||||
|
|
||||||
time.Sleep(statsdSleepTime)
|
time.Sleep(statsdSleepTime)
|
||||||
suite.Equal("mtg.concurrency_limited:1|c", suite.statsdServer.String())
|
suite.Equal("mtg.concurrency_limited:1|c", suite.statsdServer.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *StatsdTestSuite) TestEventIPBlocklisted() {
|
func (suite *StatsdTestSuite) TestEventIPBlocklisted() {
|
||||||
suite.statsd.EventIPBlocklisted(mtglib.EventIPBlocklisted{
|
suite.statsd.EventIPBlocklisted(
|
||||||
CreatedAt: time.Now(),
|
mtglib.NewEventIPBlocklisted(net.ParseIP("10.0.0.10")))
|
||||||
RemoteIP: net.ParseIP("10.0.0.10"),
|
|
||||||
})
|
|
||||||
|
|
||||||
time.Sleep(statsdSleepTime)
|
time.Sleep(statsdSleepTime)
|
||||||
suite.Equal("mtg.ip_blocklisted:1|c", suite.statsdServer.String())
|
suite.Equal("mtg.ip_blocklisted:1|c", suite.statsdServer.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *StatsdTestSuite) TestEventReplayAttack() {
|
func (suite *StatsdTestSuite) TestEventReplayAttack() {
|
||||||
suite.statsd.EventReplayAttack(mtglib.EventReplayAttack{
|
suite.statsd.EventReplayAttack(mtglib.NewEventReplayAttack("connID"))
|
||||||
CreatedAt: time.Now(),
|
|
||||||
ConnID: "connID",
|
|
||||||
})
|
|
||||||
|
|
||||||
time.Sleep(statsdSleepTime)
|
time.Sleep(statsdSleepTime)
|
||||||
suite.Equal("mtg.replay_attacks:1|c", suite.statsdServer.String())
|
suite.Equal("mtg.replay_attacks:1|c", suite.statsdServer.String())
|
||||||
|
|||||||
Reference in New Issue
Block a user