func (mod *module) forwardMessage(e *e3x.Endpoint, x *e3x.Exchange, msg []byte, pipe *e3x.Pipe, reason error) error { var ( token = cipherset.ExtractToken(msg) ex = mod.lookupToken(token) ) // not a bridged message if ex == nil { return nil } // handle bridged message dst := ex.ActivePipe() if dst == pipe { return nil } buf := bufpool.New().Set(msg) _, err := dst.Write(buf) buf.Free() if err != nil { mod.log.To(ex.RemoteHashname()).Printf("\x1B[35mFWD %x %s error=%s\x1B[0m", token, dst.RemoteAddr(), err) return nil } else { mod.log.To(ex.RemoteHashname()).Printf("\x1B[35mFWD %x %s\x1B[0m", token, dst.RemoteAddr()) return e3x.ErrStopPropagation } }
func (mod *module) receivedForwardedMessage(e *e3x.Endpoint, x *e3x.Exchange, msg []byte, pipe *e3x.Pipe, reason error) error { var ( token = cipherset.ExtractToken(msg) conn = mod.lookupConnection(x, token) ) if conn == nil { return nil } conn.halfPipe.PushMessage(msg) return e3x.ErrStopPropagation }
func (mod *module) handle_peer(ch *e3x.Channel) { defer ch.Kill() log := mod.log.From(ch.RemoteHashname()).To(mod.e.LocalHashname()) // MUST allow router role if mod.config.DisableRouter { log.Println("drop: router disabled") return } pkt, err := ch.ReadPacket() if err != nil { log.Printf("drop: failed to read packet: %s", err) return } peerStr, ok := pkt.Header().GetString("peer") if !ok { log.Printf("drop: no peer in packet") return } peer := hashname.H(peerStr) // MUST have link to either endpoint if mod.e.GetExchange(ch.RemoteHashname()) == nil && mod.e.GetExchange(peer) == nil { log.Printf("drop: no link to either peer") return } // MUST pass firewall if mod.config.AllowPeer != nil && !mod.config.AllowPeer(ch.RemoteHashname(), peer) { log.Printf("drop: blocked by firewall") return } ex := mod.e.GetExchange(peer) if ex == nil { log.Printf("drop: no exchange to target") // resolve? return } token := cipherset.ExtractToken(pkt.Body(nil)) if token != cipherset.ZeroToken { // add bridge back to requester mod.RouteToken(token, ch.Exchange()) } mod.connect(ex, bufpool.New().Set(pkt.Body(nil))) }
func (e *Endpoint) accept(conn net.Conn) { var ( token cipherset.Token msg = bufpool.New() err error n int ) n, err = conn.Read(msg.RawBytes()[:1500]) if err != nil { msg.Free() conn.Close() return } msg.SetLen(n) // msg is either a handshake or a channel packet // when msg is a handshake decrypt it and pass it to the associated exchange // when msg is a channel packet lookup the exchange and pass it the msg // always associate the conn with the exchange if msg.Len() < 2 { if e.endpointHooks.DropPacket(msg.Get(nil), conn, nil) != ErrStopPropagation { conn.Close() } msg.Free() return // to short } token = cipherset.ExtractToken(msg.RawBytes()) e.mtx.Lock() exchange := e.tokens[token] e.mtx.Unlock() if exchange != nil { exchange.received(newMessage(msg, newPipe(e.transport, conn, nil, exchange))) return } if raw := msg.RawBytes(); len(raw) < 3 || raw[0] != 0 || raw[1] != 1 { if e.endpointHooks.DropPacket(msg.Get(nil), conn, nil) != ErrStopPropagation { conn.Close() } msg.Free() return // to short } localIdent, err := e.LocalIdentity() if err != nil { if e.endpointHooks.DropPacket(msg.Get(nil), conn, err) != ErrStopPropagation { conn.Close() } e.traceDroppedPacket(msg.Get(nil), conn, err.Error()) msg.Free() return // drop } // handle handshakes e.mtx.Lock() defer e.mtx.Unlock() var ( csid = msg.RawBytes()[2] key = e.keys[csid] ) if key == nil { if e.endpointHooks.DropPacket(msg.Get(nil), conn, nil) != ErrStopPropagation { conn.Close() } msg.Free() return // no key for csid } handshake, err := cipherset.DecryptHandshake(csid, key, msg.RawBytes()[3:]) if err != nil { if e.endpointHooks.DropPacket(msg.Get(nil), conn, err) != ErrStopPropagation { conn.Close() } e.traceDroppedPacket(msg.Get(nil), conn, err.Error()) msg.Free() return // drop } hn, err := hashname.FromKeyAndIntermediates(csid, handshake.PublicKey().Public(), handshake.Parts()) if err != nil { if e.endpointHooks.DropPacket(msg.Get(nil), conn, err) != ErrStopPropagation { conn.Close() } e.traceDroppedPacket(msg.Get(nil), conn, err.Error()) msg.Free() return // drop } exchange = e.hashnames[hn] if exchange != nil { oldLocalToken := exchange.LocalToken() oldRemoteToken := exchange.RemoteToken() exchange.received(newMessage(msg, newPipe(e.transport, conn, nil, exchange))) newLocalToken := exchange.LocalToken() newRemoteToken := exchange.RemoteToken() if oldLocalToken != newLocalToken { delete(e.tokens, oldLocalToken) e.tokens[newLocalToken] = exchange } if oldRemoteToken != newRemoteToken { delete(e.tokens, oldRemoteToken) e.tokens[newRemoteToken] = exchange } return } exchange, err = newExchange(localIdent, nil, handshake, e.log, registerEndpoint(e)) if err != nil { if e.endpointHooks.DropPacket(msg.Get(nil), conn, err) != ErrStopPropagation { conn.Close() } e.traceDroppedPacket(msg.Get(nil), conn, err.Error()) msg.Free() return // drop } e.hashnames[hn] = exchange e.tokens[exchange.LocalToken()] = exchange e.tokens[exchange.RemoteToken()] = exchange exchange.state = ExchangeDialing exchange.received(newMessage(msg, newPipe(e.transport, conn, nil, exchange))) }