// set sets the given items using the given conflict resolution policy.
// The returned slice will have the same length as the input slice.
// If value is not nil, each element should correspond to an item.
func set(c appengine.Context, item []*Item, value [][]byte, policy int32) []os.Error {
	req := &pb.MemcacheSetRequest{
		Item: make([]*pb.MemcacheSetRequest_Item, len(item)),
	}
	for i, t := range item {
		p := &pb.MemcacheSetRequest_Item{
			Key: []byte(t.Key),
		}
		if value == nil {
			p.Value = t.Value
		} else {
			p.Value = value[i]
		}
		if t.Flags != 0 {
			p.Flags = proto.Uint32(t.Flags)
		}
		if t.Expiration != 0 {
			// In the .proto file, MemcacheSetRequest_Item uses a fixed32 (i.e. unsigned)
			// for expiration time, while MemcacheGetRequest_Item uses int32 (i.e. signed).
			// Throughout this .go file, we use int32.
			p.ExpirationTime = proto.Uint32(uint32(t.Expiration))
		}
		if t.casID != 0 {
			p.CasId = proto.Uint64(t.casID)
			p.ForCas = proto.Bool(true)
		}
		p.SetPolicy = pb.NewMemcacheSetRequest_SetPolicy(policy)
		req.Item[i] = p
	}
	res := &pb.MemcacheSetResponse{}
	e := make([]os.Error, len(item))
	if err := c.Call("memcache", "Set", req, res); err != nil {
		for i := range e {
			e[i] = err
		}
		return e
	}
	if len(e) != len(res.SetStatus) {
		for i := range e {
			e[i] = ErrServerError
		}
		return e
	}
	for i := range e {
		switch res.SetStatus[i] {
		case pb.MemcacheSetResponse_STORED:
			e[i] = nil
		case pb.MemcacheSetResponse_NOT_STORED:
			e[i] = ErrNotStored
		case pb.MemcacheSetResponse_EXISTS:
			e[i] = ErrCASConflict
		default:
			e[i] = ErrServerError
		}
	}
	return e
}
Beispiel #2
0
// The last part of authentication runs in the server's synchronous handler.
func (server *Server) finishAuthenticate(client *Client) {
	// If the client succeeded in proving to the server that it should be granted
	// the credentials of a registered user, do some sanity checking to make sure
	// that user isn't already connected.
	//
	// If the user is already connected, try to check whether this new client is
	// connecting from the same IP address. If that's the case, disconnect the
	// previous client and let the new guy in.
	if client.user != nil {
		found := false
		for _, connectedClient := range server.clients {
			if connectedClient.UserId() == client.UserId() {
				found = true
				break
			}
		}
		// The user is already present on the server.
		if found {
			// todo(mkrautz): Do the address checking.
			client.RejectAuth("UsernameInUse", "A client is already connected using those credentials.")
			return
		}

		// No, that user isn't already connected. Move along.
	}

	// Add the client to the connected list
	client.Session = server.GenSessionId()
	server.clients[client.Session] = client

	// First, check whether we need to tell the other connected
	// clients to switch to a codec so the new guy can actually speak.
	server.updateCodecVersions()

	client.sendChannelList()

	// Add the client to the host slice for its host address.
	host := client.tcpaddr.IP.String()
	server.hmutex.Lock()
	server.hclients[host] = append(server.hclients[host], client)
	server.hmutex.Unlock()

	userstate := &mumbleproto.UserState{
		Session:   proto.Uint32(client.Session),
		Name:      proto.String(client.ShownName()),
		ChannelId: proto.Uint32(0),
	}
	if client.IsRegistered() {
		userstate.UserId = proto.Uint32(uint32(client.UserId()))

		if client.user.HasTexture() {
			// Does the client support blobs?
			if client.Version >= 0x10203 {
				userstate.TextureHash = client.user.TextureBlobHashBytes()
			} else {
				buf, err := globalBlobstore.Get(client.user.TextureBlob)
				if err != nil {
					log.Panicf("Blobstore error: %v", err.String())
				}
				userstate.Texture = buf
			}
		}

		if client.user.HasComment() {
			// Does the client support blobs?
			if client.Version >= 0x10203 {
				userstate.CommentHash = client.user.CommentBlobHashBytes()
			} else {
				buf, err := globalBlobstore.Get(client.user.CommentBlob)
				if err != nil {
					log.Panicf("Blobstore error: %v", err.String())
				}
				userstate.Comment = proto.String(string(buf))
			}
		}
	}

	server.userEnterChannel(client, server.root, userstate)
	if err := server.broadcastProtoMessage(MessageUserState, userstate); err != nil {
		// Server panic?
	}

	server.sendUserList(client)

	sync := &mumbleproto.ServerSync{}
	sync.Session = proto.Uint32(client.Session)
	sync.MaxBandwidth = proto.Uint32(server.MaxBandwidth)
	if client.IsSuperUser() {
		sync.Permissions = proto.Uint64(uint64(AllPermissions))
	} else {
		server.HasPermission(client, server.root, EnterPermission)
		perm := server.aclcache.GetPermission(client, server.root)
		if !perm.IsCached() {
			client.Panic("Corrupt ACL cache")
			return
		}
		perm.ClearCacheBit()
		sync.Permissions = proto.Uint64(uint64(perm))
	}
	if err := client.sendProtoMessage(MessageServerSync, sync); err != nil {
		client.Panic(err.String())
		return
	}

	err := client.sendProtoMessage(MessageServerConfig, &mumbleproto.ServerConfig{
		AllowHtml:          proto.Bool(true),
		MessageLength:      proto.Uint32(1000),
		ImageMessageLength: proto.Uint32(1000),
	})
	if err != nil {
		client.Panic(err.String())
		return
	}

	client.state = StateClientReady
	client.clientReady <- true
}
Beispiel #3
0
func (db *Db) Execute(trans *Transaction) (ret *TransactionReturn) {
	var err os.Error

	/*
		bytes, err := proto.Marshal(trans)
		if err != nil {
			panic(fmt.Sprintf("Got an error marshalling: %s", err))
		}

		newtrans := NewEmptyTransaction()
		err = proto.Unmarshal(bytes, newtrans)
		if err != nil {
			panic(fmt.Sprintf("Got an error unmarshalling: %s", err))
		}


		newtrans.Id = proto.Uint64(db.getNextTransactionId())

		token := Token(0) // TODO: Use real token!!
		vs := db.viewstateManager.createViewState(token, true, 0)

		err = newtrans.init()
		if err != nil {
			panic(fmt.Sprintf("Transaction initialisation error: %s", err))
		}

		ret = newtrans.execute(vs)
		bytes, err = proto.Marshal(ret)
		if err != nil {
			panic(fmt.Sprintf("Got an error marshalling: %s", err))
		}

		newret := new(TransactionReturn)
		err = proto.Unmarshal(bytes, newret)
		if err != nil {
			panic(fmt.Sprintf("Got an error unmarshalling: %s", err))
		}
		//*/

	//*
	trans.Id = proto.Uint64(db.getNextTransactionId())
	token := Token(0) // TODO: Use real token!!
	ti := &transactionInfo{
		token:    Token(0),
		readOnly: true,
	}
	trans.init(ti)
	vs := db.viewstateManager.createViewState(token, ti.readOnly, true, 0)
	newret := trans.execute(vs)
	//*/

	if newret.Error == nil {
		err = vs.prepareCommit()
		if err != nil {
			vs.rollback()

			newret.Error = &TransactionError{
				Id:      proto.Uint32(0), // TODO: ERRNO
				Message: proto.String(err.String()),
			}
			return newret
		}

		err = vs.commit()
		if err != nil {
			newret.Error = &TransactionError{
				Id:      proto.Uint32(0), // TODO: ERRNO
				Message: proto.String(err.String()),
			}
			return newret
		}
	}

	return newret

}