1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "net/dns/dns_session.h"
7 #include "base/basictypes.h"
9 #include "base/rand_util.h"
10 #include "base/stl_util.h"
11 #include "base/time.h"
12 #include "net/base/ip_endpoint.h"
13 #include "net/base/net_errors.h"
14 #include "net/dns/dns_config_service.h"
15 #include "net/dns/dns_socket_pool.h"
16 #include "net/socket/stream_socket.h"
17 #include "net/udp/datagram_client_socket.h"
21 DnsSession::SocketLease::SocketLease(scoped_refptr
<DnsSession
> session
,
22 unsigned server_index
,
23 scoped_ptr
<DatagramClientSocket
> socket
)
24 : session_(session
), server_index_(server_index
), socket_(socket
.Pass()) {}
26 DnsSession::SocketLease::~SocketLease() {
27 session_
->FreeSocket(server_index_
, socket_
.Pass());
30 DnsSession::DnsSession(const DnsConfig
& config
,
31 scoped_ptr
<DnsSocketPool
> socket_pool
,
32 const RandIntCallback
& rand_int_callback
,
35 socket_pool_(socket_pool
.Pass()),
36 rand_callback_(base::Bind(rand_int_callback
, 0, kuint16max
)),
39 socket_pool_
->Initialize(&config_
.nameservers
, net_log
);
42 DnsSession::~DnsSession() {
45 int DnsSession::NextQueryId() const {
46 return rand_callback_
.Run();
49 int DnsSession::NextFirstServerIndex() {
50 int index
= server_index_
;
52 server_index_
= (server_index_
+ 1) % config_
.nameservers
.size();
56 base::TimeDelta
DnsSession::NextTimeout(int attempt
) {
57 // The timeout doubles every full round (each nameserver once).
58 // TODO(szym): Adapt timeout to observed RTT. http://crbug.com/110197
59 return config_
.timeout
* (1 << (attempt
/ config_
.nameservers
.size()));
62 // Allocate a socket, already connected to the server address.
63 scoped_ptr
<DnsSession::SocketLease
> DnsSession::AllocateSocket(
64 unsigned server_index
,
65 const NetLog::Source
& source
) {
66 scoped_ptr
<DatagramClientSocket
> socket
;
68 socket
= socket_pool_
->AllocateSocket(server_index
);
70 return scoped_ptr
<SocketLease
>(NULL
);
72 socket
->NetLog().BeginEvent(
73 NetLog::TYPE_SOCKET_IN_USE
,
74 source
.ToEventParametersCallback());
76 SocketLease
* lease
= new SocketLease(this, server_index
, socket
.Pass());
77 return scoped_ptr
<SocketLease
>(lease
);
80 scoped_ptr
<StreamSocket
> DnsSession::CreateTCPSocket(
81 unsigned server_index
,
82 const NetLog::Source
& source
) {
83 return socket_pool_
->CreateTCPSocket(server_index
, source
);
87 void DnsSession::FreeSocket(
88 unsigned server_index
,
89 scoped_ptr
<DatagramClientSocket
> socket
) {
92 socket
->NetLog().EndEvent(NetLog::TYPE_SOCKET_IN_USE
);
94 socket_pool_
->FreeSocket(server_index
, socket
.Pass());