OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2013 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. | |
4 | |
5 #include "cloud_print/gcp20/prototype/printer.h" | |
6 | |
7 #include <ifaddrs.h> | |
8 #include <netdb.h> | |
9 | |
10 #include "base/command_line.h" | |
11 #include "base/strings/string_number_conversions.h" | |
12 | |
13 namespace { | |
14 | |
15 const char* kServiceNamePrefix = "first_privet_device"; | |
16 const char* kServiceDomainName = "my.privet.device.local"; | |
17 | |
18 const uint16 kDefaultTTL = 60*60; | |
19 const uint16 kDefaultHttpPort = 10101; | |
20 | |
21 uint16 ReadHttpPortFromCommandLine() { | |
22 uint32 http_port_tmp = kDefaultHttpPort; | |
23 | |
24 std::string http_port_string_tmp = | |
25 CommandLine::ForCurrentProcess()->GetSwitchValueASCII("http-port"); | |
26 base::StringToUint(http_port_string_tmp, &http_port_tmp); | |
27 | |
28 if (http_port_tmp > kuint32max) { | |
29 LOG(ERROR) << "Port " << http_port_tmp << " is too large (maximum is " << | |
30 kDefaultHttpPort << "). Using default port."; | |
31 | |
32 http_port_tmp = kDefaultHttpPort; | |
33 } | |
34 | |
35 VLOG(1) << "HTTP port for responses: " << http_port_tmp; | |
36 return static_cast<uint16>(http_port_tmp); | |
37 } | |
38 | |
39 uint16 ReadTtlFromCommandLine() { | |
40 uint32 ttl = kDefaultTTL; | |
41 | |
Vitaly Buka (NO REVIEWS)
2013/06/14 23:46:52
base::StringToUint(
CommandLine::ForCurrentPro
maksymb
2013/06/15 01:02:22
Done.
| |
42 std::string ttl_string_tmp = | |
43 CommandLine::ForCurrentProcess()->GetSwitchValueASCII("ttl"); | |
44 base::StringToUint(ttl_string_tmp, &ttl); | |
45 | |
46 VLOG(1) << "TTL for announcements: " << ttl; | |
47 return ttl; | |
48 } | |
49 | |
50 // Returns pointer to local IP address number. Examples for interface name | |
51 // are: "wlan0", "eth0", NULL (find first acceptable except "lo"). | |
52 net::IPAddressNumber GetLocalIp(const char* interface_name) { | |
53 ifaddrs* ifaddr = NULL; | |
Vitaly Buka (NO REVIEWS)
2013/06/14 23:46:52
move both this closer where it used first time
maksymb
2013/06/15 01:02:22
Done.
| |
54 char host[NI_MAXHOST] = {0}; | |
55 | |
56 net::IPAddressNumber result; // |result| is empty if no interface found. | |
57 if (getifaddrs(&ifaddr) == -1) { | |
Vitaly Buka (NO REVIEWS)
2013/06/14 23:46:52
ifaddr -> first_address
ifa -> address
maksymb
2013/06/15 01:02:22
I think "ifa" means "interface". Done.
| |
58 LOG(ERROR) << "getifaddrs() failed"; | |
59 return result; | |
60 } | |
61 | |
62 // Browse all interfaces. | |
63 for (ifaddrs* ifa = ifaddr; ifa; ifa = ifa->ifa_next) { | |
64 if (!ifa->ifa_addr) | |
65 continue; | |
66 | |
67 // Get additional info about current interface. | |
68 int rv = getnameinfo(ifa->ifa_addr, | |
69 sizeof(*ifa->ifa_addr), | |
70 host, | |
71 NI_MAXHOST, | |
72 NULL, | |
73 0, | |
74 NI_NUMERICHOST); | |
75 | |
76 if (ifa->ifa_addr->sa_family == AF_INET) { | |
77 // Find interface we need. | |
78 if (interface_name ? (strcmp(ifa->ifa_name, interface_name) == 0) | |
79 : (strcmp(ifa->ifa_name, "lo") != 0)) { | |
80 if (rv != 0) { | |
81 LOG(ERROR) << "getnameinfo() failed: " << gai_strerror(rv); | |
82 break; | |
83 } | |
84 | |
85 net::ParseIPLiteralToNumber(host, &result); | |
86 } | |
87 } | |
88 } | |
89 | |
90 // Erase memory under list of interfaces. | |
91 freeifaddrs(ifaddr); | |
92 return result; | |
93 } | |
94 | |
95 } // namespace | |
96 | |
97 Printer::Printer() : initialized_(false) { | |
98 } | |
99 | |
100 Printer::~Printer() { | |
101 Stop(); | |
102 } | |
103 | |
104 bool Printer::Start() { | |
105 if (initialized_) | |
106 return true; | |
107 | |
108 // TODO(maksymb): Add possibility to control interface via command line args. | |
109 net::IPAddressNumber ip = GetLocalIp(NULL); | |
110 if (ip.empty()) { | |
111 LOG(ERROR) << "No local IP found. Cannot start printer."; | |
112 return false; | |
113 } | |
114 VLOG(1) << "Local address: " << net::IPAddressToString(ip); | |
115 | |
116 // Starting DNS-SD server. | |
117 initialized_ = dns_server_.Start( | |
118 new PrivetDnsResponseBuilderFactory(kServiceNamePrefix, | |
119 kServiceDomainName, | |
120 ip, | |
121 ReadHttpPortFromCommandLine()), | |
122 ReadTtlFromCommandLine()); | |
123 return initialized_; | |
124 } | |
125 | |
126 void Printer::Stop() { | |
127 if (!initialized_) | |
128 return; | |
129 | |
130 dns_server_.Shutdown(); | |
131 } | |
132 | |
OLD | NEW |