Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
RyanJarv committed Oct 21, 2021
0 parents commit 634627b
Show file tree
Hide file tree
Showing 8 changed files with 205 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.idea
10 changes: 10 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
FROM golang:latest

WORKDIR /usr/src/little-stitch
ENV GO11MODULES on
RUN apt-get update && apt-get install -y \
libpcap-dev \
iproute2
COPY ./go.mod ./go.sum ./*.go ./
RUN go build -o /usr/local/bin/little-stitch ./main.go
ENTRYPOINT ["/usr/local/bin/little-stitch"]
3 changes: 3 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module github.com/RyanJarv/little-stitch

go 1.17
Empty file added go.sum
Empty file.
84 changes: 84 additions & 0 deletions lib/send.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package lib

import (
"fmt"
"io"
"syscall"
"time"
)

const TIMEOUT = time.Second
const BASE_PORT = 60000

func NewConnection(addr [4]byte) *io.PipeWriter {
r, w := io.Pipe()
go connection(addr, r)
return w
}

func connection(addr [4]byte, in *io.PipeReader) error {
for {
var b []byte
_, err := in.Read(b)
if err != nil {
return err
}

// Send clock ping, notifies the server we are starting the next byte.
_, err = Ping(&syscall.SockaddrInet4{Addr: addr, Port: BASE_PORT})
if err != nil {
fmt.Printf("[ERROR] Recieved error when sending clock ping: %s\n", err)
}
for _, b := range b {
for i := 1; i <= 8; i++ {
err := sendBit(addr, b, i)
if err != nil {
fmt.Printf("[ERROR] Recieved error when sending bit %d: %s\n", i, err)
}
}
}
}
}

func sendBit(addr [4]byte, b byte, bit int) error {
if (int(b) & bit) == 1 {
_, err := Ping(&syscall.SockaddrInet4{Addr: addr, Port: BASE_PORT + bit})
return err
}
return nil
}

func Ping(addr syscall.Sockaddr) (bool, error) {
sock, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_STREAM, syscall.IPPROTO_TCP)
if err != nil {
return false, fmt.Errorf("creating socket: %w\n", err)
}
defer func(sock int) {
err := syscall.Close(sock)
if err != nil {
fmt.Printf("Failed to close socket %d\n", sock)
}
}(sock)

//fmt.Println("socket resp: ", sock)

err = syscall.Connect(sock, addr)
for err == syscall.EINTR {
err = syscall.Connect(sock, addr)
}

start := time.Now()
_, err = syscall.Getpeername(sock)

for err != nil {
if err.Error() == "invalid argument" {
return false, fmt.Errorf("connection rejected")
} else if time.Now().After(start.Add(TIMEOUT)) {
return false, fmt.Errorf("connection timedout")
} else if err.Error() == "socket is not connected" {
time.Sleep(TIMEOUT / 20)
_, err = syscall.Getpeername(sock)
}
}
return true, nil
}
65 changes: 65 additions & 0 deletions lib/send_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package lib

import (
"syscall"
"testing"
)

func TestPing(t *testing.T) {
type args struct {
addr syscall.Sockaddr
}
tests := []struct {
name string
args args
want bool
wantErr bool
}{
{
"returns true and no error when ran against a open port",
args{
&syscall.SockaddrInet4{
Port: 80,
Addr: [4]byte{1,1,1,1},
},
},
true,
false,
},
{
"returns false and an error when ran against a filtered port",
args{
&syscall.SockaddrInet4{
Port: 1234,
Addr: [4]byte{1,1,1,1},
},
},
true,
false,
},
{
"returns false and an error when ran against a closed port",
args{
&syscall.SockaddrInet4{
Port: 1234,
Addr: [4]byte{127, 0, 0, 1},
},
},
true,
false,
},
// TODO: Add test cases.
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := Ping(tt.args.addr)
if (err != nil) != tt.wantErr {
t.Errorf("Ping() error = %v, wantErr %v", err, tt.wantErr)
return
}
if got != tt.want {
t.Errorf("Ping() got = %v, want %v", got, tt.want)
}
})
}
}
26 changes: 26 additions & 0 deletions lib/sync.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package lib

import (
"sync"
"time"
)

type Syncer struct {
Delay time.Duration
Functions []func()
}

func (s *Syncer) Start() *sync.WaitGroup {
wg := &sync.WaitGroup{}
go func() {
for _, f := range s.Functions {
wg.Add(1)
go func(f func()) {
f()
wg.Done()
}(f)
}
time.Sleep(s.Delay)
}()
return wg
}
16 changes: 16 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package main

import (
"fmt"
"github.com/RyanJarv/little-stitch/lib"
"io"
)

func main() {
conn := lib.NewConnection([4]byte{34, 125, 181, 202})

_, err := io.WriteString(conn, "Hello!")
if err != nil {
fmt.Printf("failed to write to connection: %s\n", err)
}
}

0 comments on commit 634627b

Please sign in to comment.