func doResponses(conn *tao.Conn) {
	defer conn.Close()

	var peer *string
	if conn.Peer() != nil {
		peer = proto.String(conn.Peer().String())
		verbose.Printf("Processing connection requests for peer %s\n", *peer)
		netlog.Log("rendezvous: connection from peer %s", *peer)
	} else {
		verbose.Printf("Processing connection requests for anonymous peer\n")
		netlog.Log("rendezvous: connection from anonymous")
	}

	for {
		var req rendezvous.Request
		if err := conn.ReadMessage(&req); err != nil {
			if err != io.EOF {
				doError(conn, err, rendezvous.ResponseStatus_RENDEZVOUS_BAD_REQUEST, "failed to read request")
			}
			break
		}
		doResponse(&req, conn, peer)
	}
	lock.Lock()
	for k, v := range bindings {
		if v.expiration.IsZero() && v.conn == conn {
			delete(bindings, k)
			verbose.Printf("Expired binding upon close: %s\n", k)
		}
	}
	lock.Unlock()
	verbose.Println("Done processing connection requests")

	if peer == nil {
		netlog.Log("rendezvous: connection closed from anonymous")
	} else {
		netlog.Log("rendezvous: connection closed from peer %s", *peer)
	}
}
Exemple #2
0
func doResponseWithoutStats(conn *tao.Conn) {
	verbose.Println("Processing request")
	doResponse(conn)
}
func doResponse(req *rendezvous.Request, conn *tao.Conn, peer *string) {
	verbose.Println("Processing request")

	// Check whether the request is well-formed
	switch *req.Type {
	case rendezvous.RequestType_RENDEZVOUS_REGISTER:
		b := req.Binding
		if b == nil {
			doError(conn, nil, rendezvous.ResponseStatus_RENDEZVOUS_BAD_REQUEST, "missing binding")
			return
		}
		if !allowAnon && peer == nil {
			doError(conn, nil, rendezvous.ResponseStatus_RENDEZVOUS_REQUEST_DENIED, "anonymous registration forbidden")
			return
		}
		if b.Principal != nil && (peer == nil || *b.Principal != *peer) {
			doError(conn, nil, rendezvous.ResponseStatus_RENDEZVOUS_BAD_REQUEST, "third party registration forbidden")
			return
		}
		approved := register(conn, b, peer)
		if !approved {
			doError(conn, nil, rendezvous.ResponseStatus_RENDEZVOUS_REQUEST_DENIED, "request is denied")
			return
		}
		status := rendezvous.ResponseStatus_RENDEZVOUS_OK
		resp := &rendezvous.Response{Status: &status}
		sendResponse(conn, resp)

	case rendezvous.RequestType_RENDEZVOUS_LOOKUP:
		q := ".*"
		if req.Query != nil {
			q = *req.Query
		}
		r, err := regexp.Compile(q)
		if err != nil {
			doError(conn, err, rendezvous.ResponseStatus_RENDEZVOUS_BAD_REQUEST, "bad query")
			return
		}
		var matches []*rendezvous.Binding
		lock.Lock()
		expire(time.Now())
		for k, v := range bindings {
			if r.MatchString(k) {
				b := v.Binding
				matches = append(matches, &b)
			}
		}
		lock.Unlock()
		fmt.Printf("Query [%s] ==> %d matches\n", q, len(matches))
		status := rendezvous.ResponseStatus_RENDEZVOUS_OK
		resp := &rendezvous.Response{Status: &status, Bindings: matches}
		sendResponse(conn, resp)

	case rendezvous.RequestType_RENDEZVOUS_POLICY:
		var policy string
		if manualMode {
			policy = "manual"
		} else if fcfsMode {
			policy = "fcfs"
		} else {
			policy = "unspecified"
		}
		if allowAnon {
			policy = "anon," + policy
		}
		status := rendezvous.ResponseStatus_RENDEZVOUS_OK
		resp := &rendezvous.Response{Status: &status, Policy: &policy}
		sendResponse(conn, resp)
	default:
		doError(conn, nil, rendezvous.ResponseStatus_RENDEZVOUS_BAD_REQUEST, "unrecognized request type")
		return
	}
}