source: trunk/synergy/lib/net/CNetworkAddress.cpp

Last change on this file was 2749, checked in by bird, 19 years ago

synergy v1.3.1 sources (zip).

File size: 4.7 KB
Line 
1/*
2 * synergy -- mouse and keyboard sharing utility
3 * Copyright (C) 2002 Chris Schoeneman
4 *
5 * This package is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * found in the file COPYING that should have accompanied this file.
8 *
9 * This package is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 */
14
15#include "CNetworkAddress.h"
16#include "XSocket.h"
17#include "CArch.h"
18#include "XArch.h"
19#include <cstdlib>
20
21//
22// CNetworkAddress
23//
24
25// name re-resolution adapted from a patch by Brent Priddy.
26
27CNetworkAddress::CNetworkAddress() :
28 m_address(NULL),
29 m_hostname(),
30 m_port(0)
31{
32 // note -- make no calls to CNetwork socket interface here;
33 // we're often called prior to CNetwork::init().
34}
35
36CNetworkAddress::CNetworkAddress(int port) :
37 m_address(NULL),
38 m_hostname(),
39 m_port(port)
40{
41 checkPort();
42 m_address = ARCH->newAnyAddr(IArchNetwork::kINET);
43 ARCH->setAddrPort(m_address, m_port);
44}
45
46CNetworkAddress::CNetworkAddress(const CNetworkAddress& addr) :
47 m_address(addr.m_address != NULL ? ARCH->copyAddr(addr.m_address) : NULL),
48 m_hostname(addr.m_hostname),
49 m_port(addr.m_port)
50{
51 // do nothing
52}
53
54CNetworkAddress::CNetworkAddress(const CString& hostname, int port) :
55 m_address(NULL),
56 m_hostname(hostname),
57 m_port(port)
58{
59 // check for port suffix
60 CString::size_type i = m_hostname.rfind(':');
61 if (i != CString::npos && i + 1 < m_hostname.size()) {
62 // found a colon. see if it looks like an IPv6 address.
63 bool colonNotation = false;
64 bool dotNotation = false;
65 bool doubleColon = false;
66 for (CString::size_type j = 0; j < i; ++j) {
67 if (m_hostname[j] == ':') {
68 colonNotation = true;
69 dotNotation = false;
70 if (m_hostname[j + 1] == ':') {
71 doubleColon = true;
72 }
73 }
74 else if (m_hostname[j] == '.' && colonNotation) {
75 dotNotation = true;
76 }
77 }
78
79 // port suffix is ambiguous with IPv6 notation if there's
80 // a double colon and the end of the address is not in dot
81 // notation. in that case we assume it's not a port suffix.
82 // the user can replace the double colon with zeros to
83 // disambiguate.
84 if ((!doubleColon || dotNotation) || !colonNotation) {
85 // parse port from hostname
86 char* end;
87 const char* chostname = m_hostname.c_str();
88 long suffixPort = strtol(chostname + i + 1, &end, 10);
89 if (end == chostname + i + 1 || *end != '\0') {
90 throw XSocketAddress(XSocketAddress::kBadPort,
91 m_hostname, m_port);
92 }
93
94 // trim port from hostname
95 m_hostname.erase(i);
96
97 // save port
98 m_port = static_cast<int>(suffixPort);
99 }
100 }
101
102 // check port number
103 checkPort();
104}
105
106CNetworkAddress::~CNetworkAddress()
107{
108 if (m_address != NULL) {
109 ARCH->closeAddr(m_address);
110 }
111}
112
113CNetworkAddress&
114CNetworkAddress::operator=(const CNetworkAddress& addr)
115{
116 CArchNetAddress newAddr = NULL;
117 if (addr.m_address != NULL) {
118 newAddr = ARCH->copyAddr(addr.m_address);
119 }
120 if (m_address != NULL) {
121 ARCH->closeAddr(m_address);
122 }
123 m_address = newAddr;
124 m_hostname = addr.m_hostname;
125 m_port = addr.m_port;
126 return *this;
127}
128
129void
130CNetworkAddress::resolve()
131{
132 // discard previous address
133 if (m_address != NULL) {
134 ARCH->closeAddr(m_address);
135 m_address = NULL;
136 }
137
138 try {
139 // if hostname is empty then use wildcard address otherwise look
140 // up the name.
141 if (m_hostname.empty()) {
142 m_address = ARCH->newAnyAddr(IArchNetwork::kINET);
143 }
144 else {
145 m_address = ARCH->nameToAddr(m_hostname);
146 }
147 }
148 catch (XArchNetworkNameUnknown&) {
149 throw XSocketAddress(XSocketAddress::kNotFound, m_hostname, m_port);
150 }
151 catch (XArchNetworkNameNoAddress&) {
152 throw XSocketAddress(XSocketAddress::kNoAddress, m_hostname, m_port);
153 }
154 catch (XArchNetworkNameUnsupported&) {
155 throw XSocketAddress(XSocketAddress::kUnsupported, m_hostname, m_port);
156 }
157 catch (XArchNetworkName&) {
158 throw XSocketAddress(XSocketAddress::kUnknown, m_hostname, m_port);
159 }
160
161 // set port in address
162 ARCH->setAddrPort(m_address, m_port);
163}
164
165bool
166CNetworkAddress::operator==(const CNetworkAddress& addr) const
167{
168 return ARCH->isEqualAddr(m_address, addr.m_address);
169}
170
171bool
172CNetworkAddress::operator!=(const CNetworkAddress& addr) const
173{
174 return !operator==(addr);
175}
176
177bool
178CNetworkAddress::isValid() const
179{
180 return (m_address != NULL);
181}
182
183const CArchNetAddress&
184CNetworkAddress::getAddress() const
185{
186 return m_address;
187}
188
189int
190CNetworkAddress::getPort() const
191{
192 return m_port;
193}
194
195CString
196CNetworkAddress::getHostname() const
197{
198 return m_hostname;
199}
200
201void
202CNetworkAddress::checkPort()
203{
204 // check port number
205 if (m_port <= 0 || m_port > 65535) {
206 throw XSocketAddress(XSocketAddress::kBadPort, m_hostname, m_port);
207 }
208}
Note: See TracBrowser for help on using the repository browser.