aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd/main.go27
-rw-r--r--slowpoke.go7
2 files changed, 22 insertions, 12 deletions
diff --git a/cmd/main.go b/cmd/main.go
index db3f185..93f62b0 100644
--- a/cmd/main.go
+++ b/cmd/main.go
@@ -15,11 +15,11 @@ import (
var log = logging.MustGetLogger("main")
var opts struct {
- TargetAddress string `short:"t" long:"target" description:"TODO" required:"true"`
- Port int `short:"p" long:"port" description:"TODO" required:"true"`
- Verbose []bool `short:"v" long:"verbose" description:"TODO"`
- Latency time.Duration `short:"l" long:"latency" default:"0ms" description:"TODO"`
- BufferSize int `short:"b" long:"buffer" default:"1500" description:"TODO"`
+ TargetAddress string `short:"t" long:"target" description:"The target address in host:port form" required:"true"`
+ Port int `short:"p" long:"port" description:"The port Slowpoke should listen for connections on" required:"true"`
+ Verbose []bool `short:"v" long:"verbose" description:"Log verbosity level. -v or -vv"`
+ Latency time.Duration `short:"l" long:"latency" default:"0ms" description:"The amount of latency to apply to data packets, specified as a number and unit. E.g. 15ms or 2s. Supported units are 'us', 'ms', 's', 'm' and 'h'"`
+ BufferSize int `short:"b" long:"buffer" default:"1500" description:"The size of the transfer buffer in bytes. Latency is applied between each buffer flush. Therefore total latency applied is equal to '(totalDataTransferred/bufferSize) * latency'"`
}
func init() {
@@ -51,8 +51,10 @@ func configureLogger() {
func main() {
log.Infof("Proxying between :%d and %s with %s of latency", opts.Port, opts.TargetAddress, opts.Latency)
log.Debugf("Transfer buffer size set to %d bytes", opts.BufferSize)
+
listener := getListener(opts.Port)
- waitForClients(listener)
+ targetAddr := resolveTarget(opts.TargetAddress)
+ waitForClients(listener, targetAddr)
}
func getListener(port int) net.Listener {
@@ -66,7 +68,16 @@ func getListener(port int) net.Listener {
return listener
}
-func waitForClients(listener net.Listener) {
+func resolveTarget(targetAddress string) *net.TCPAddr {
+ tcpAddr, err := net.ResolveTCPAddr("tcp", opts.TargetAddress)
+ if err != nil {
+ log.Errorf("Failed to resolve target address %s:\n%v", opts.TargetAddress, err)
+ os.Exit(1)
+ }
+ return tcpAddr
+}
+
+func waitForClients(listener net.Listener, targetAddr *net.TCPAddr) {
for {
client, err := listener.Accept()
if err != nil {
@@ -75,7 +86,7 @@ func waitForClients(listener net.Listener) {
}
log.Infof("Accepted connection from client %v\n", client.RemoteAddr())
- s := slowpoke.New(client, opts.TargetAddress, opts.Latency, opts.BufferSize, log)
+ s := slowpoke.New(client, targetAddr, opts.Latency, opts.BufferSize, log)
go s.StartTransfer()
}
diff --git a/slowpoke.go b/slowpoke.go
index 98182f6..4a36306 100644
--- a/slowpoke.go
+++ b/slowpoke.go
@@ -10,7 +10,7 @@ import (
type Slowpoke struct {
conn net.Conn
- targetAddr string
+ targetAddr *net.TCPAddr
latency time.Duration
bufferSize int
isClosed bool
@@ -18,7 +18,7 @@ type Slowpoke struct {
logger *logging.Logger
}
-func New(conn net.Conn, targetAddr string, latency time.Duration, bufferSize int, logger *logging.Logger) *Slowpoke {
+func New(conn net.Conn, targetAddr *net.TCPAddr, latency time.Duration, bufferSize int, logger *logging.Logger) *Slowpoke {
return &Slowpoke{
conn: conn,
targetAddr: targetAddr,
@@ -32,9 +32,8 @@ func New(conn net.Conn, targetAddr string, latency time.Duration, bufferSize int
func (s *Slowpoke) StartTransfer() {
defer s.conn.Close()
- target, err := net.Dial("tcp", s.targetAddr)
+ target, err := net.DialTCP("tcp", nil, s.targetAddr)
if err != nil {
- // TODO validate target addr before this point
s.logger.Errorf("Failed to connect to target address %s:\n%v", s.targetAddr, err)
return
}