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) } }
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 } }