This source file includes following definitions.
- server_initial_flow_control_receive_window_
- server_initial_flow_control_receive_window_
- Initialize
- Listen
- WaitForEvents
- Shutdown
- OnEvent
- ReadAndDispatchSinglePacket
#include "net/tools/quic/quic_server.h"
#include <errno.h>
#include <features.h>
#include <netinet/in.h>
#include <string.h>
#include <sys/epoll.h>
#include <sys/socket.h>
#include "net/base/ip_endpoint.h"
#include "net/quic/congestion_control/tcp_receiver.h"
#include "net/quic/crypto/crypto_handshake.h"
#include "net/quic/crypto/quic_random.h"
#include "net/quic/quic_clock.h"
#include "net/quic/quic_crypto_stream.h"
#include "net/quic/quic_data_reader.h"
#include "net/quic/quic_protocol.h"
#include "net/tools/quic/quic_in_memory_cache.h"
#include "net/tools/quic/quic_socket_utils.h"
#define MMSG_MORE 0
#ifndef SO_RXQ_OVFL
#define SO_RXQ_OVFL 40
#endif
const int kEpollFlags = EPOLLIN | EPOLLOUT | EPOLLET;
static const char kSourceAddressTokenSecret[] = "secret";
const uint32 kServerInitialFlowControlWindow = 100 * net::kMaxPacketSize;
namespace net {
namespace tools {
QuicServer::QuicServer()
: port_(0),
fd_(-1),
packets_dropped_(0),
overflow_supported_(false),
use_recvmmsg_(false),
crypto_config_(kSourceAddressTokenSecret, QuicRandom::GetInstance()),
supported_versions_(QuicSupportedVersions()),
server_initial_flow_control_receive_window_(
kServerInitialFlowControlWindow) {
config_.SetDefaults();
config_.set_initial_round_trip_time_us(kMaxInitialRoundTripTimeUs, 0);
config_.set_server_initial_congestion_window(kMaxInitialWindow,
kDefaultInitialWindow);
Initialize();
}
QuicServer::QuicServer(const QuicConfig& config,
const QuicVersionVector& supported_versions,
uint32 server_initial_flow_control_receive_window)
: port_(0),
fd_(-1),
packets_dropped_(0),
overflow_supported_(false),
use_recvmmsg_(false),
config_(config),
crypto_config_(kSourceAddressTokenSecret, QuicRandom::GetInstance()),
supported_versions_(supported_versions),
server_initial_flow_control_receive_window_(
server_initial_flow_control_receive_window) {
Initialize();
}
void QuicServer::Initialize() {
#if MMSG_MORE
use_recvmmsg_ = true;
#endif
epoll_server_.set_timeout_in_us(50 * 1000);
QuicInMemoryCache::GetInstance();
QuicEpollClock clock(&epoll_server_);
scoped_ptr<CryptoHandshakeMessage> scfg(
crypto_config_.AddDefaultConfig(
QuicRandom::GetInstance(), &clock,
QuicCryptoServerConfig::ConfigOptions()));
}
QuicServer::~QuicServer() {
}
bool QuicServer::Listen(const IPEndPoint& address) {
port_ = address.port();
int address_family = address.GetSockAddrFamily();
fd_ = socket(address_family, SOCK_DGRAM | SOCK_NONBLOCK, IPPROTO_UDP);
if (fd_ < 0) {
LOG(ERROR) << "CreateSocket() failed: " << strerror(errno);
return false;
}
int rc = QuicSocketUtils::SetGetAddressInfo(fd_, address_family);
if (rc < 0) {
LOG(ERROR) << "IP detection not supported" << strerror(errno);
return false;
}
int get_overflow = 1;
rc = setsockopt(
fd_, SOL_SOCKET, SO_RXQ_OVFL, &get_overflow, sizeof(get_overflow));
if (rc < 0) {
DLOG(WARNING) << "Socket overflow detection not supported";
} else {
overflow_supported_ = true;
}
int get_local_ip = 1;
rc = setsockopt(fd_, IPPROTO_IP, IP_PKTINFO,
&get_local_ip, sizeof(get_local_ip));
if (rc == 0 && address_family == AF_INET6) {
rc = setsockopt(fd_, IPPROTO_IPV6, IPV6_RECVPKTINFO,
&get_local_ip, sizeof(get_local_ip));
}
if (rc != 0) {
LOG(ERROR) << "Failed to set required socket options";
return false;
}
rc = setsockopt(fd_, SOL_SOCKET, SO_RCVBUF,
&TcpReceiver::kReceiveWindowTCP,
sizeof(TcpReceiver::kReceiveWindowTCP));
if (rc != 0) {
LOG(ERROR) << "Failed to set socket recv size";
return false;
}
rc = setsockopt(fd_, SOL_SOCKET, SO_SNDBUF,
&TcpReceiver::kReceiveWindowTCP,
sizeof(TcpReceiver::kReceiveWindowTCP));
if (rc != 0) {
LOG(ERROR) << "Failed to set socket send size";
return false;
}
sockaddr_storage raw_addr;
socklen_t raw_addr_len = sizeof(raw_addr);
CHECK(address.ToSockAddr(reinterpret_cast<sockaddr*>(&raw_addr),
&raw_addr_len));
rc = bind(fd_,
reinterpret_cast<const sockaddr*>(&raw_addr),
sizeof(raw_addr));
if (rc < 0) {
LOG(ERROR) << "Bind failed: " << strerror(errno);
return false;
}
DVLOG(1) << "Listening on " << address.ToString();
if (port_ == 0) {
SockaddrStorage storage;
IPEndPoint server_address;
if (getsockname(fd_, storage.addr, &storage.addr_len) != 0 ||
!server_address.FromSockAddr(storage.addr, storage.addr_len)) {
LOG(ERROR) << "Unable to get self address. Error: " << strerror(errno);
return false;
}
port_ = server_address.port();
DVLOG(1) << "Kernel assigned port is " << port_;
}
epoll_server_.RegisterFD(fd_, this, kEpollFlags);
dispatcher_.reset(new QuicDispatcher(
config_,
crypto_config_,
supported_versions_,
&epoll_server_,
server_initial_flow_control_receive_window_));
dispatcher_->Initialize(fd_);
return true;
}
void QuicServer::WaitForEvents() {
epoll_server_.WaitForEventsAndExecuteCallbacks();
}
void QuicServer::Shutdown() {
dispatcher_->Shutdown();
close(fd_);
fd_ = -1;
}
void QuicServer::OnEvent(int fd, EpollEvent* event) {
DCHECK_EQ(fd, fd_);
event->out_ready_mask = 0;
if (event->in_events & EPOLLIN) {
DVLOG(1) << "EPOLLIN";
bool read = true;
while (read) {
read = ReadAndDispatchSinglePacket(
fd_, port_, dispatcher_.get(),
overflow_supported_ ? &packets_dropped_ : NULL);
}
}
if (event->in_events & EPOLLOUT) {
dispatcher_->OnCanWrite();
if (dispatcher_->HasPendingWrites()) {
event->out_ready_mask |= EPOLLOUT;
}
}
if (event->in_events & EPOLLERR) {
}
}
bool QuicServer::ReadAndDispatchSinglePacket(int fd,
int port,
QuicDispatcher* dispatcher,
uint32* packets_dropped) {
char buf[2 * kMaxPacketSize];
IPEndPoint client_address;
IPAddressNumber server_ip;
int bytes_read =
QuicSocketUtils::ReadPacket(fd, buf, arraysize(buf),
packets_dropped,
&server_ip, &client_address);
if (bytes_read < 0) {
return false;
}
QuicEncryptedPacket packet(buf, bytes_read, false);
IPEndPoint server_address(server_ip, port);
dispatcher->ProcessPacket(server_address, client_address, packet);
return true;
}
}
}