Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor sending and receiving of packets #25

Merged
merged 15 commits into from
Jul 22, 2017
5 changes: 0 additions & 5 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,6 @@ go:
- 1.8
- tip

before_install:
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get install -q libpcap-dev ; fi
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update ; fi
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install libpcap ; fi

install: make install_ci

script: make test
Expand Down
12 changes: 8 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,6 @@ DC-to-External-Services issues by generating minimal traffic:
(accidental or not)
- Whether network-level SLAs are met

## Requirements

* libpcap

## Usage

There are two ways to use the Arachne package.
Expand Down Expand Up @@ -73,6 +69,14 @@ as root user, by being granted `CAP_NET_RAW` capability
(see: [capabilities][]).


### Note on BPF filtering

When receiving packets, Arachne attempts to apply a BPF filter to the raw socket
so that processing of packets occurs on a much smaller set of (ones destined
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"of ..."? Parenthesis needed or not?

specifically for Arachne agent testing). This is currently supported only on
Linux and thus performance will be significantly worse on BSD-based systems
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

significantly?

where a larger number of packets must be inspected.

<hr>

Released under the [MIT License](LICENSE.md).
Expand Down
23 changes: 18 additions & 5 deletions bootstrap.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
"github.com/uber/arachne/collector"
"github.com/uber/arachne/config"
d "github.com/uber/arachne/defines"
"github.com/uber/arachne/internal/ip"
"github.com/uber/arachne/internal/log"
"github.com/uber/arachne/internal/tcp"
"github.com/uber/arachne/internal/util"
Expand Down Expand Up @@ -86,6 +87,9 @@ func Run(ec *config.Extended, opts ...Option) {
logger.Error("error initializing stats", zap.Error(err))
}

// Hold raw socket connection for IPv4 packets
var connIPv4 *ip.Conn

logger.Info("Starting up arachne")

for {
Expand Down Expand Up @@ -120,7 +124,7 @@ func Run(ec *config.Extended, opts ...Option) {
dnsRefresh := time.NewTicker(d.DNSRefreshInterval)
dnsWg.Add(1)
killC.DNSRefresh = make(chan struct{})
config.ResolveDnsTargets(gl.Remotes, gl.RemoteConfig, dnsRefresh, &dnsWg,
config.ResolveDNSTargets(gl.Remotes, gl.RemoteConfig, dnsRefresh, &dnsWg,
killC.DNSRefresh, logger)
dnsWg.Wait()
logger.Debug("Remotes after DNS resolution include",
Expand All @@ -132,6 +136,16 @@ func Run(ec *config.Extended, opts ...Option) {
sentC := make(chan tcp.Message, d.ChannelOutBufferSize)
rcvdC := make(chan tcp.Message, d.ChannelInBufferSize)

// Connection for IPv4 packets
if connIPv4 == nil {
connIPv4 = ip.NewConn(
d.AfInet,
uint32(gl.RemoteConfig.TargetTCPPort),
gl.RemoteConfig.InterfaceName,
gl.RemoteConfig.SrcAddress,
logger)
}

// Actual echoing is a percentage of the total configured batch cycle duration.
realBatchInterval := time.Duration(float32(gl.RemoteConfig.BatchInterval) *
d.BatchIntervalEchoingPerc)
Expand All @@ -150,8 +164,7 @@ func Run(ec *config.Extended, opts ...Option) {
if !*gl.CLI.SenderOnlyMode {
// Listen for responses or probes from other IPv4 arachne agents.
killC.Receiver = make(chan struct{})
err = tcp.Receiver("ip4", &gl.RemoteConfig.SrcAddress, gl.RemoteConfig.TargetTCPPort,
gl.RemoteConfig.InterfaceName, sentC, rcvdC, killC.Receiver, logger)
err = tcp.Receiver(connIPv4, gl.RemoteConfig.TargetTCPPort, sentC, rcvdC, killC.Receiver, logger)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is gl.RemoteConfig.TargetTCPPort redundant here? Can it not be extracted from connIPv4?

if err != nil {
logger.Fatal("IPv4 receiver failed to start", zap.Error(err))
}
Expand All @@ -163,7 +176,7 @@ func Run(ec *config.Extended, opts ...Option) {
logger.Debug("Echoing...")
// Start echoing all targets.
killC.Echo = make(chan struct{})
tcp.EchoTargets(gl.Remotes, &gl.RemoteConfig.SrcAddress, gl.RemoteConfig.TargetTCPPort,
tcp.EchoTargets(gl.Remotes, connIPv4, gl.RemoteConfig.TargetTCPPort,
gl.RemoteConfig.SrcTCPPortRange, gl.RemoteConfig.QoSEnabled, &currentDSCP,
realBatchInterval, batchEndCycle, sentC, *gl.CLI.SenderOnlyMode,
completeCycleUpload, &finishedCycleUpload, killC.Echo, logger)
Expand All @@ -179,7 +192,7 @@ func Run(ec *config.Extended, opts ...Option) {
logger.Debug("Received SIG")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line 187 exceeds the 120 char width limit.

configRefresh.Stop()
util.CleanUpAll(killC, *gl.CLI.ReceiverOnlyMode, *gl.CLI.SenderOnlyMode,
gl.RemoteConfig.ResolveDNS, gl.App.PIDPath, sr, logger)
gl.RemoteConfig.ResolveDNS, connIPv4, gl.App.PIDPath, sr, logger)
logger.Info("Exiting")
os.Exit(0)
}
Expand Down
8 changes: 4 additions & 4 deletions collector/collector_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ func TestRun(t *testing.T) {
Type: tcp.EchoRequest,
SrcAddr: source,
DstAddr: target,
Af: network.Family(&target),
Af: defines.AfInet,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mind if we keep the following import consistent?
import defines as d

Copy link
Contributor Author

@henridevieux henridevieux Jul 10, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Importing of defines was previous code. We can address changing defines to d throughout the entire codebase in a separate diff.

SrcPort: sp,
QosDSCP: currentDSCP,
Ts: tcp.Timestamp{
Expand All @@ -131,7 +131,7 @@ func TestRun(t *testing.T) {
Type: tcp.EchoReply,
SrcAddr: target,
DstAddr: source,
Af: network.Family(&source),
Af: defines.AfInet,
SrcPort: sp,
QosDSCP: currentDSCP,
Ts: tcp.Timestamp{
Expand All @@ -146,7 +146,7 @@ func TestRun(t *testing.T) {
Type: tcp.EchoRequest,
SrcAddr: source,
DstAddr: unreachableTarget,
Af: network.Family(&unreachableTarget),
Af: defines.AfInet,
SrcPort: sp,
QosDSCP: currentDSCP,
Ts: tcp.Timestamp{
Expand All @@ -160,7 +160,7 @@ func TestRun(t *testing.T) {
Type: tcp.EchoRequest,
SrcAddr: sourceIPv6,
DstAddr: targetIPv6,
Af: network.Family(&targetIPv6),
Af: defines.AfInet6,
SrcPort: sp,
QosDSCP: currentDSCP,
Ts: tcp.Timestamp{
Expand Down
6 changes: 3 additions & 3 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -606,8 +606,8 @@ func walkTargets(grc *RemoteConfig, ts []target, ext bool, remotes RemoteStore,
}
}

// ResolveDnsTargets resolves the DNS names of the IP addresses of all echo targets and the localhost.
func ResolveDnsTargets(
// ResolveDNSTargets resolves the DNS names of the IP addresses of all echo targets and the localhost.
func ResolveDNSTargets(
remotes RemoteStore,
grc *RemoteConfig,
DNSRefresh *time.Ticker,
Expand Down Expand Up @@ -658,7 +658,7 @@ func ResolveDnsTargets(
continue
case <-kill:
DNSRefresh.Stop()
logger.Debug("ResolveDnsTargets goroutine returning")
logger.Debug("ResolveDNSTargets goroutine returning")
return
}
}
Expand Down
1 change: 1 addition & 0 deletions defines/defines.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ const (
PcapMaxSnapLen = 128
PortHTTP = 80
PortHTTPS = 443
TCPWindowSize = 0xaaaa
TimestampPayloadLengthBytes = 15
)

Expand Down
12 changes: 8 additions & 4 deletions glide.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion glide.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import:
- package: github.com/google/gopacket
version: ^1
subpackages:
- pcap
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was due gopacket's pcap timeout minimum value of 1ms.

That is unfortunate.

- layers
- package: github.com/jawher/mow.cli
- package: github.com/miekg/dns
Expand All @@ -18,9 +17,13 @@ import:
version: ^1
subpackages:
- zapcore
- package: golang.org/x/net
subpackages:
- bpf
- package: gopkg.in/validator.v2
- package: gopkg.in/yaml.v2
testImport:
- package: github.com/stretchr/testify
subpackages:
- assert
- require
Loading