func sendAuthRequest(requestId, domain, ip, id, mechanism, credentials string) (Status, error) {
	sock, err := czmq.NewReq(ZAP_ENDPOINT)
	if err != nil {
		return InternalError, fmt.Errorf("Error creating new REQ for %s: %s", ZAP_ENDPOINT, err)
	}

	err = sock.SendMessage([][]byte{
		[]byte(ZAP_VERSION), //The version frame, which SHALL contain the three octets "1.0".
		[]byte(requestId),   //The request id, which MAY contain an opaque binary blob.
		[]byte(domain),      //The domain, which SHALL contain a string.
		[]byte(ip),          //The address, the origin network IP address.
		[]byte(id),          //The identity, the connection Identity, if any.
		[]byte(mechanism),   //The mechanism, which SHALL contain a string.
		[]byte(credentials), //The credentials, which SHALL be zero or more opaque frames.
	})
	if err != nil {
		return InternalError, fmt.Errorf("Error in SendMessage: %s", err)
	}

	reply, err := sock.RecvMessage()
	//for i, x := range reply { log.Printf("reply %d: %s", i, string(x)) }

	if err != nil {
		return InternalError, fmt.Errorf("Error in SendMessage: %s", err)
	}

	// SPEC: The version frame, which SHALL contain the three octets "1.0".
	if !bytes.Equal(reply[0], []byte(ZAP_VERSION)) {
		return InternalError, fmt.Errorf("Expected first frame to be `%s`.", ZAP_VERSION)
	}

	// SPEC: The request id, which MAY contain an opaque binary blob.
	if !bytes.Equal(reply[1], []byte(requestId)) {
		return InternalError, fmt.Errorf("Request ID did not match")
	}

	// SPEC: The status code, which SHALL contain a string.
	status := Status(reply[2])
	reason := string(reply[3])
	switch status {
	case Success:
		return status, nil
	case TemporaryError:
		return status, fmt.Errorf("Temporary Error: %s", reason)
	case AuthenticationFailure:
		return status, fmt.Errorf("Authentication Failure: %s", reason)
	case InternalError:
		return status, fmt.Errorf("Internal Server Error: %s", reason)
	default:
		return status, fmt.Errorf("Invalid status code: %s", status)
	}

	// SPEC: The status text, which MAY contain a string.
	// SPEC: The user id, which SHALL contain a string.
	// SPEC: The metadata, which MAY contain a blob.
}
func (s *SocketType) Create(endpoint string) (sock *czmq.Sock, err error) {
	log.Printf("New `%s` on `%s`", s, endpoint)
	switch *s {
	case REQ:
		return czmq.NewReq(endpoint)
	case DEALER:
		return czmq.NewDealer(endpoint)
	case SUB:
		return czmq.NewSub(endpoint, "")
	}

	return nil, &InvalidSocketTypeError{*s}
}