Example #1
0
func deleteMessages(conn *transport.Conn, inBuf []byte, outBuf []byte, t *testing.T, messageList []*[32]byte) {
	deleteMessages := &proto.ClientToServer{
		DeleteMessages: proto.ToProtoByte32List(messageList),
	}
	writeProtobuf(conn, outBuf, deleteMessages, t)

	receiveProtobuf(conn, inBuf, t)
}
Example #2
0
func DeleteMessages(connToServer *ConnectionToServer, messageList []*[32]byte) error {
	deleteMessages := &proto.ClientToServer{
		DeleteMessages: proto.ToProtoByte32List(messageList),
	}
	if err := WriteProtobuf(connToServer.Conn, deleteMessages); err != nil {
		return err
	}

	_, err := ReceiveReply(connToServer)
	return err
}
Example #3
0
//for each client, listen for commands
func (server *Server) handleClient(connection net.Conn) error {
	defer server.wg.Done()
	newConnection, uid, err := transport.Handshake(connection, server.pk, server.sk, nil, proto.SERVER_MESSAGE_SIZE) //TODO: Decide on this bound
	if err != nil {
		return err
	}

	commands := make(chan *proto.ClientToServer)
	disconnected := make(chan error)
	server.wg.Add(2)
	go server.readClientCommands(newConnection, commands, disconnected)
	go server.handleClientShutdown(newConnection)

	var notificationsUnbuffered, notifications chan *MessageWithId
	var notifyEnabled bool
	defer func() {
		if notifyEnabled {
			server.notifier.StopWaitingSync(uid, notificationsUnbuffered)
		}
	}()

	outBuf := make([]byte, proto.SERVER_MESSAGE_SIZE)
	response := new(proto.ServerToClient)
	for {
		select {
		case err := <-disconnected:
			return err
		case cmd := <-commands:
			if cmd.CreateAccount != nil && *cmd.CreateAccount {
				err = server.newUser(uid)
			} else if cmd.DeliverEnvelope != nil {
				msg_id, err := server.newMessage((*[32]byte)(cmd.DeliverEnvelope.User),
					cmd.DeliverEnvelope.Envelope)
				if err != nil {
					return err
				}
				response.MessageId = (*proto.Byte32)(msg_id)
			} else if cmd.ListMessages != nil && *cmd.ListMessages {
				var messageList []*[32]byte
				messageList, err = server.getMessageList(uid)
				response.MessageList = proto.ToProtoByte32List(messageList)
			} else if cmd.DownloadEnvelope != nil {
				response.Envelope, err = server.getEnvelope(uid, (*[32]byte)(cmd.DownloadEnvelope))
				response.MessageId = cmd.DownloadEnvelope
			} else if cmd.DeleteMessages != nil {
				messageList := cmd.DeleteMessages
				err = server.deleteMessages(uid, proto.To32ByteList(messageList))
			} else if cmd.UploadSignedKeys != nil {
				err = server.newKeys(uid, cmd.UploadSignedKeys)
			} else if cmd.GetSignedKey != nil {
				response.SignedKey, err = server.getKey((*[32]byte)(cmd.GetSignedKey))
			} else if cmd.GetNumKeys != nil {
				response.NumKeys, err = server.getNumKeys(uid)
			} else if cmd.ReceiveEnvelopes != nil {
				if *cmd.ReceiveEnvelopes && !notifyEnabled {
					notifyEnabled = true
					notificationsUnbuffered = server.notifier.StartWaiting(uid)
					notifications = make(chan *MessageWithId)
					server.wg.Add(1)
					go server.readClientNotifications(notificationsUnbuffered, notifications)
				} else if !*cmd.ReceiveEnvelopes && notifyEnabled {
					server.notifier.StopWaitingSync(uid, notificationsUnbuffered)
					notifyEnabled = false
				}
			}
			if err != nil {
				fmt.Printf("Server error: %v\n", err)
				response.Status = proto.ServerToClient_PARSE_ERROR.Enum()
			} else {
				response.Status = proto.ServerToClient_OK.Enum()
			}
			if err = server.writeProtobuf(newConnection, outBuf, response); err != nil {
				return err
			}
			commands <- cmd
		case notification, ok := <-notifications:
			if !notifyEnabled {
				continue
			}
			if !ok {
				notifyEnabled = false
				go server.notifier.StopWaitingSync(uid, notificationsUnbuffered)
				continue
			}
			response.Envelope = notification.Envelope
			response.MessageId = (*proto.Byte32)(notification.Id)
			response.Status = proto.ServerToClient_OK.Enum()
			if err = server.writeProtobuf(newConnection, outBuf, response); err != nil {
				return err
			}
		}
		response.Reset()
	}
}