wip
This commit is contained in:
		| @@ -2,11 +2,10 @@ | ||||
|  | ||||
| ## Refactoring for Testability | ||||
|  | ||||
| * [ ] connWriter | ||||
|   * [ ] Separate send/relay calls | ||||
| * [x] connWriter | ||||
| * [x] mcWriter | ||||
| * [x] ifWriter | ||||
| * [ ] ifReader | ||||
| * [ ] ifReader (testing) | ||||
| * [ ] connReader | ||||
| * [ ] mcReader | ||||
| * [ ] hubPoller | ||||
|   | ||||
| @@ -68,18 +68,18 @@ func newConnWriter(conn udpAddrPortWriter, localIP byte) *connWriter { | ||||
|  | ||||
| // Not safe for concurrent use. Should only be called by supervisor. | ||||
| func (w *connWriter) SendControlPacket(pkt marshaller, route *peerRoute) { | ||||
| 	buf := pkt.Marshal(w.cBuf1) | ||||
| 	h := header{ | ||||
| 		StreamID: controlStreamID, | ||||
| 		Counter:  atomic.AddUint64(&w.counters[route.IP], 1), | ||||
| 		SourceIP: w.localIP, | ||||
| 		DestIP:   route.IP, | ||||
| 	} | ||||
| 	buf = route.ControlCipher.Encrypt(h, buf, w.cBuf2) | ||||
| 	buf := w.encryptControlPacket(pkt, route) | ||||
| 	w.writeTo(buf, route.RemoteAddr) | ||||
| } | ||||
|  | ||||
| // Relay control packet. Routes must not be nil. | ||||
| func (w *connWriter) RelayControlPacket(pkt marshaller, route, relay *peerRoute) { | ||||
| 	buf := w.encryptControlPacket(pkt, route) | ||||
| 	w.relayPacket(buf, w.cBuf1, route, relay) | ||||
| } | ||||
|  | ||||
| // Encrypted packet will occupy cBuf2. | ||||
| func (w *connWriter) encryptControlPacket(pkt marshaller, route *peerRoute) []byte { | ||||
| 	buf := pkt.Marshal(w.cBuf1) | ||||
| 	h := header{ | ||||
| 		StreamID: controlStreamID, | ||||
| @@ -87,12 +87,11 @@ func (w *connWriter) RelayControlPacket(pkt marshaller, route, relay *peerRoute) | ||||
| 		SourceIP: w.localIP, | ||||
| 		DestIP:   route.IP, | ||||
| 	} | ||||
| 	buf = route.ControlCipher.Encrypt(h, buf, w.cBuf2) | ||||
| 	w.relayPacket(buf, w.cBuf1, route, relay) | ||||
| 	return route.ControlCipher.Encrypt(h, buf, w.cBuf2) | ||||
| } | ||||
|  | ||||
| // Not safe for concurrent use. Should only be called by ifReader. | ||||
| func (w *connWriter) SendDataPacket(pkt []byte, route, relay *peerRoute) { | ||||
| func (w *connWriter) SendDataPacket(pkt []byte, route *peerRoute) { | ||||
| 	h := header{ | ||||
| 		StreamID: dataStreamID, | ||||
| 		Counter:  atomic.AddUint64(&w.counters[route.IP], 1), | ||||
| @@ -101,16 +100,21 @@ func (w *connWriter) SendDataPacket(pkt []byte, route, relay *peerRoute) { | ||||
| 	} | ||||
|  | ||||
| 	enc := route.DataCipher.Encrypt(h, pkt, w.dBuf1) | ||||
|  | ||||
| 	if route.Direct { | ||||
| 		w.writeTo(enc, route.RemoteAddr) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	w.relayPacket(enc, w.dBuf2, route, relay) | ||||
| 	w.writeTo(enc, route.RemoteAddr) | ||||
| } | ||||
|  | ||||
| // TODO: RelayDataPacket | ||||
| // Relay a data packet. Routes must not be nil. | ||||
| func (w *connWriter) RelayDataPacket(pkt []byte, route, relay *peerRoute) { | ||||
| 	h := header{ | ||||
| 		StreamID: dataStreamID, | ||||
| 		Counter:  atomic.AddUint64(&w.counters[route.IP], 1), | ||||
| 		SourceIP: w.localIP, | ||||
| 		DestIP:   route.IP, | ||||
| 	} | ||||
|  | ||||
| 	enc := route.DataCipher.Encrypt(h, pkt, w.dBuf1) | ||||
| 	w.relayPacket(enc, w.dBuf2, route, relay) | ||||
| } | ||||
|  | ||||
| // Safe for concurrent use. Should only be called by connReader. | ||||
| // | ||||
| @@ -122,10 +126,6 @@ func (w *connWriter) SendEncryptedDataPacket(pkt []byte, route *peerRoute) { | ||||
| } | ||||
|  | ||||
| func (w *connWriter) relayPacket(data, buf []byte, route, relay *peerRoute) { | ||||
| 	if relay == nil || !relay.Up { | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	h := header{ | ||||
| 		StreamID: dataStreamID, | ||||
| 		Counter:  atomic.AddUint64(&w.counters[relay.IP], 1), | ||||
|   | ||||
| @@ -126,7 +126,7 @@ func TestConnWriter_SendControlPacket_direct(t *testing.T) { | ||||
| } | ||||
|  | ||||
| // Testing if we can relay a packet via an intermediary. | ||||
| func TestConnWriter_SendControlPacket_relay(t *testing.T) { | ||||
| func TestConnWriter_RelayControlPacket_relay(t *testing.T) { | ||||
| 	route, rRoute, relay, rRelay := testConnWriter_getTestRoutes() | ||||
|  | ||||
| 	writer := &testUDPAddrPortWriter{} | ||||
| @@ -159,40 +159,6 @@ func TestConnWriter_SendControlPacket_relay(t *testing.T) { | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Testing that a nil relay doesn't cause an issue. | ||||
| func TestConnWriter_SendControlPacket_relay_relayNil(t *testing.T) { | ||||
| 	route, rRoute, _, _ := testConnWriter_getTestRoutes() | ||||
|  | ||||
| 	writer := &testUDPAddrPortWriter{} | ||||
| 	w := newConnWriter(writer, rRoute.IP) | ||||
| 	in := testPacket("hello world!") | ||||
|  | ||||
| 	w.RelayControlPacket(in, route, nil) | ||||
|  | ||||
| 	out := writer.Written() | ||||
| 	if len(out) != 0 { | ||||
| 		t.Fatal(out) | ||||
| 	} | ||||
|  | ||||
| } | ||||
|  | ||||
| // Testing that we don't send anything if the relay isn't up. | ||||
| func TestConnWriter_SendControlPacket_relay_relayNotUp(t *testing.T) { | ||||
| 	route, rRoute, relay, _ := testConnWriter_getTestRoutes() | ||||
| 	relay.Up = false | ||||
|  | ||||
| 	writer := &testUDPAddrPortWriter{} | ||||
| 	w := newConnWriter(writer, rRoute.IP) | ||||
| 	in := testPacket("hello world!") | ||||
|  | ||||
| 	w.RelayControlPacket(in, route, relay) | ||||
|  | ||||
| 	out := writer.Written() | ||||
| 	if len(out) != 0 { | ||||
| 		t.Fatal(out) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Testing that we can send a data packet directly to a remote route. | ||||
| func TestConnWriter_SendDataPacket_direct(t *testing.T) { | ||||
| 	route, rRoute, _, _ := testConnWriter_getTestRoutes() | ||||
| @@ -202,7 +168,7 @@ func TestConnWriter_SendDataPacket_direct(t *testing.T) { | ||||
| 	w := newConnWriter(writer, rRoute.IP) | ||||
|  | ||||
| 	in := []byte("hello world!") | ||||
| 	w.SendDataPacket(in, route, nil) | ||||
| 	w.SendDataPacket(in, route) | ||||
|  | ||||
| 	out := writer.Written() | ||||
| 	if len(out) != 1 { | ||||
| @@ -224,14 +190,14 @@ func TestConnWriter_SendDataPacket_direct(t *testing.T) { | ||||
| } | ||||
|  | ||||
| // Testing that we can relay a data packet via a relay. | ||||
| func TestConnWriter_SendDataPacket_relay(t *testing.T) { | ||||
| func TestConnWriter_RelayDataPacket_relay(t *testing.T) { | ||||
| 	route, rRoute, relay, rRelay := testConnWriter_getTestRoutes() | ||||
|  | ||||
| 	writer := &testUDPAddrPortWriter{} | ||||
| 	w := newConnWriter(writer, rRoute.IP) | ||||
| 	in := []byte("Hello world!") | ||||
|  | ||||
| 	w.SendDataPacket(in, route, relay) | ||||
| 	w.RelayDataPacket(in, route, relay) | ||||
|  | ||||
| 	out := writer.Written() | ||||
| 	if len(out) != 1 { | ||||
| @@ -257,35 +223,26 @@ func TestConnWriter_SendDataPacket_relay(t *testing.T) { | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Testing that we don't attempt to relay if the relay is nil. | ||||
| func TestConnWriter_SendDataPacket_relay_relayNil(t *testing.T) { | ||||
| // Testing that we can send an already encrypted packet. | ||||
| func TestConnWriter_SendEncryptedDataPacket(t *testing.T) { | ||||
| 	route, rRoute, _, _ := testConnWriter_getTestRoutes() | ||||
|  | ||||
| 	writer := &testUDPAddrPortWriter{} | ||||
| 	w := newConnWriter(writer, rRoute.IP) | ||||
| 	in := []byte("Hello world!") | ||||
|  | ||||
| 	w.SendDataPacket(in, route, nil) | ||||
| 	w.SendEncryptedDataPacket(in, route) | ||||
|  | ||||
| 	out := writer.Written() | ||||
| 	if len(out) != 0 { | ||||
| 	if len(out) != 1 { | ||||
| 		t.Fatal(out) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Testing that we don't attempt to relay if the relay isn't up. | ||||
| func TestConnWriter_SendDataPacket_relay_relayNotUp(t *testing.T) { | ||||
| 	route, rRoute, relay, _ := testConnWriter_getTestRoutes() | ||||
| 	relay.Up = false | ||||
| 	if out[0].Addr != route.RemoteAddr { | ||||
| 		t.Fatal(out[0]) | ||||
| 	} | ||||
|  | ||||
| 	writer := &testUDPAddrPortWriter{} | ||||
| 	w := newConnWriter(writer, rRoute.IP) | ||||
| 	in := []byte("Hello world!") | ||||
|  | ||||
| 	w.SendDataPacket(in, route, relay) | ||||
|  | ||||
| 	out := writer.Written() | ||||
| 	if len(out) != 0 { | ||||
| 		t.Fatal(out) | ||||
| 	if !bytes.Equal(out[0].Data, in) { | ||||
| 		t.Fatal(out[0]) | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -38,14 +38,14 @@ func (dc *dupCheck) IsDup(counter uint64) bool { | ||||
| 	delta := counter - dc.tailCounter | ||||
|  | ||||
| 	// Full clear. | ||||
| 	if delta >= bitSetSize { | ||||
| 	if delta >= bitSetSize-1 { | ||||
| 		dc.ClearAll() | ||||
| 		dc.Set(0) | ||||
|  | ||||
| 		dc.tail = 1 | ||||
| 		dc.head = 2 | ||||
| 		dc.tailCounter = counter + 1 | ||||
| 		dc.headCounter = dc.tailCounter - bitSetSize | ||||
| 		dc.headCounter = dc.tailCounter - bitSetSize + 1 | ||||
|  | ||||
| 		return false | ||||
| 	} | ||||
|   | ||||
| @@ -20,6 +20,18 @@ type header struct { | ||||
| 	Counter  uint64 // Init with time.Now().Unix << 30 to ensure monotonic. | ||||
| } | ||||
|  | ||||
| func parseHeader(b []byte) (h header, ok bool) { | ||||
| 	if len(b) < headerSize { | ||||
| 		return | ||||
| 	} | ||||
| 	h.Version = b[0] | ||||
| 	h.StreamID = b[1] | ||||
| 	h.SourceIP = b[2] | ||||
| 	h.DestIP = b[3] | ||||
| 	h.Counter = *(*uint64)(unsafe.Pointer(&b[4])) | ||||
| 	return h, true | ||||
| } | ||||
|  | ||||
| func (h *header) Parse(b []byte) { | ||||
| 	h.Version = b[0] | ||||
| 	h.StreamID = b[1] | ||||
|   | ||||
| @@ -57,7 +57,7 @@ func (r *ifReader) sendPacket(pkt []byte, remoteIP byte) { | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	if relay := r.relay.Load(); relay != nil { | ||||
| 	if relay := r.relay.Load(); relay != nil && relay.Up { | ||||
| 		r.relayDataPacket(pkt, route, relay) | ||||
| 	} | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user