blob: d31d027685595af5f768f9f235be6cd3280eb9a4 [file] [log] [blame]
// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef POSIX_TRANSLATION_UDP_SOCKET_H_
#define POSIX_TRANSLATION_UDP_SOCKET_H_
#include <fcntl.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <deque>
#include <utility>
#include <vector>
#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/memory/ref_counted.h"
#include "posix_translation/socket_stream.h"
#include "ppapi/cpp/completion_callback.h"
#include "ppapi/utility/completion_callback_factory.h"
namespace pp {
class NetAddress;
} // namespace pp
namespace posix_translation {
class UDPSocket : public SocketStream {
public:
UDPSocket(int fd, int socket_family, int oflag);
virtual int bind(const sockaddr* saddr, socklen_t addrlen) OVERRIDE;
virtual int connect(const sockaddr* addr, socklen_t addrlen) OVERRIDE;
virtual int setsockopt(
int level, int optname, const void* optval, socklen_t optlen) OVERRIDE;
virtual int getpeername(sockaddr* name, socklen_t* namelen) OVERRIDE;
virtual int getsockname(sockaddr* name, socklen_t* namelen) OVERRIDE;
virtual ssize_t send(const void* buf, size_t len, int flags) OVERRIDE;
virtual ssize_t sendto(const void* buf, size_t len, int flags,
const sockaddr* dest_addr, socklen_t addrlen) OVERRIDE;
virtual ssize_t recv(void* buffer, size_t len, int flags) OVERRIDE;
virtual ssize_t recvfrom(void* buffer, size_t len, int flags,
sockaddr* addr, socklen_t* addrlen) OVERRIDE;
virtual ssize_t read(void* buf, size_t count) OVERRIDE;
virtual ssize_t write(const void* buf, size_t count) OVERRIDE;
virtual bool IsSelectReadReady() const OVERRIDE;
virtual bool IsSelectWriteReady() const OVERRIDE;
virtual bool IsSelectExceptionReady() const OVERRIDE;
virtual int16_t GetPollEvents() const OVERRIDE;
virtual const char* GetStreamType() const OVERRIDE;
protected:
virtual ~UDPSocket();
virtual void OnLastFileRef() OVERRIDE;
private:
// A message unit which is sent to or received from the peer.
// Note: in libcxx, deque implementation uses sizeof(T) in the inlined
// initialization "const static" member, so we cannot use forward declaration
// here. cf): android/external/libcxx/include/deque.
struct Message {
// The address where this message is being sent to or where the message
// comes from.
sockaddr_storage addr;
// Sent or received data.
std::vector<char> data;
};
typedef std::deque<Message> MessageQueue;
class SocketWrapper;
enum State {
UDP_SOCKET_NEW,
UDP_SOCKET_BINDING,
UDP_SOCKET_BOUND,
};
bool is_block() { return !(oflag() & O_NONBLOCK); }
void CloseLocked();
void Close(int32_t result, int32_t* pres);
void Read(int32_t result);
void ReadLocked();
void OnRead(int32_t result, const pp::NetAddress& addr);
void Write(int32_t result);
void WriteLocked();
void OnWrite(int32_t result);
void PostReadTaskLocked();
void PostWriteTaskLocked();
// Number of messages in incoming queue that we can read ahead.
static const size_t kQueueSize = 16;
// Read buffer size for incoming message.
static const size_t kBufSize = 64 * 1024;
int fd_;
pp::CompletionCallbackFactory<UDPSocket> factory_;
scoped_refptr<SocketWrapper> socket_;
State state_;
MessageQueue in_queue_;
MessageQueue out_queue_;
std::vector<char> read_buf_;
bool read_sent_;
bool write_sent_;
struct sockaddr_storage connected_addr_;
DISALLOW_COPY_AND_ASSIGN(UDPSocket);
};
} // namespace posix_translation
#endif // POSIX_TRANSLATION_UDP_SOCKET_H_