Пример #1
0
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
	}
}
Пример #2
0
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
}
Пример #3
0
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)))
}
Пример #4
0
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)))
}