monotone

monotone Mtn Source Tree

Root/netxx/peer.cxx

1/*
2 * Copyright (C) 2001-2004 Peter J Jones (pjones@pmade.org)
3 * All Rights Reserved
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
14 * distribution.
15 * 3. Neither the name of the Author nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS''
20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
22 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR
23 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
26 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
27 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
29 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 */
32
33/** @file
34 * This file contains the implementation of the Netxx::Peer class.
35**/
36
37// common header
38#include "common.h"
39
40// Netxx includes
41#include <netxx/peer.h>
42
43// standard includes
44#include <algorithm>
45#include <iostream>
46#include <cstdlib>
47#include <new>
48
49//####################################################################
50namespace
51{
52 const unsigned int const_max_sockaddr_size = 128;
53}
54//###########################################################################
55Netxx::Peer::Peer (void)
56 : okay_(false), port_(0), socketfd_(-1), sockaddr_(0), sockaddr_size_(0)
57{ }
58//###########################################################################
59Netxx::Peer::Peer (const char *addr, port_type port, void *saddr, size_type saddr_size)
60 : okay_(true), addr_(addr), port_(port), socketfd_(-1), sockaddr_size_(saddr_size)
61{
62 // TODO should this be sockaddr_ = new char[saddr_size];?
63 sockaddr_ = std::malloc(saddr_size);
64 if (!sockaddr_) throw std::bad_alloc();
65
66 std::memcpy(sockaddr_, saddr, saddr_size);
67}
68//###########################################################################
69Netxx::Peer::Peer (socket_type socketfd, void *saddr, size_type saddr_size)
70 : okay_(true), port_(0), socketfd_(socketfd), sockaddr_size_(saddr_size)
71{
72 // TODO should this be sockaddr_ = new char[saddr_size];?
73 sockaddr_ = std::malloc(saddr_size);
74 if (!sockaddr_) throw std::bad_alloc();
75
76 std::memcpy(sockaddr_, saddr, saddr_size);
77 sockaddr *sa = static_cast<sockaddr*>(sockaddr_);
78
79 switch (sa->sa_family) {
80case AF_INET:
81{
82 char buffer[INET_ADDRSTRLEN];
83 if (inet_ntop(AF_INET, &(reinterpret_cast<sockaddr_in*>(sa)->sin_addr), buffer, sizeof(buffer))) {
84addr_ = buffer;
85port_ = ntohs(reinterpret_cast<sockaddr_in*>(sa)->sin_port);
86 }
87}
88break;
89
90# ifndef NETXX_NO_INET6
91case AF_INET6:
92{
93 char buffer[INET6_ADDRSTRLEN];
94 if (inet_ntop(AF_INET6, &(reinterpret_cast<sockaddr_in6*>(sa)->sin6_addr), buffer, sizeof(buffer))) {
95addr_ = buffer;
96port_ = ntohs(reinterpret_cast<sockaddr_in6*>(sa)->sin6_port);
97 }
98}
99break;
100# endif
101
102# ifndef WIN32
103case AF_LOCAL:
104 addr_ = reinterpret_cast<sockaddr_un*>(sa)->sun_path;
105 break;
106# endif
107 }
108}
109//###########################################################################
110Netxx::Peer::Peer (const Peer &other)
111 : okay_(other.okay_), addr_(other.addr_), port_(other.port_),
112 socketfd_(other.socketfd_), sockaddr_(0), sockaddr_size_(other.sockaddr_size_)
113{
114 if (other.sockaddr_) {
115sockaddr_ = std::malloc(sockaddr_size_);
116if (!sockaddr_) throw std::bad_alloc();
117std::memcpy(sockaddr_, other.sockaddr_, sockaddr_size_);
118 }
119}
120//###########################################################################
121Netxx::Peer& Netxx::Peer::operator= (const Peer &other)
122{
123 Peer tmp(other); swap(tmp);
124 return *this;
125}
126//###########################################################################
127void Netxx::Peer::swap (Peer &other)
128{
129 std::swap(okay_, other.okay_);
130 std::swap(addr_, other.addr_);
131 std::swap(port_, other.port_);
132 std::swap(socketfd_, other.socketfd_);
133 std::swap(sockaddr_, other.sockaddr_);
134 std::swap(sockaddr_size_, other.sockaddr_size_);
135}
136//###########################################################################
137Netxx::Peer::~Peer (void)
138{
139 if (sockaddr_) std::free(sockaddr_);
140}
141//###########################################################################
142const char* Netxx::Peer::get_address (void) const
143{
144 return addr_.c_str();
145}
146//###########################################################################
147Netxx::port_type Netxx::Peer::get_port (void) const
148{
149 return port_;
150}
151//###########################################################################
152Netxx::port_type Netxx::Peer::get_local_port (void) const
153{
154 os_socklen_type sa_size = const_max_sockaddr_size;
155 os_socklen_ptr_type sa_size_ptr = get_socklen_ptr(sa_size);
156
157 union {
158sockaddr sa;
159sockaddr_in sin;
160# ifndef NETXX_NO_INET6
161sockaddr_in6 sin6;
162# endif
163 } sau;
164
165 int rc;
166
167 if ( (rc = getsockname(get_socketfd(), &sau.sa, sa_size_ptr))) {
168 throw Exception(str_error(errno));
169 }
170
171 switch (sau.sa.sa_family) {
172 case AF_INET:
173 return ntohs(sau.sin.sin_port);
174
175# ifndef NETXX_NO_INET6
176 case AF_INET6:
177 return ntohs(sau.sin6.sin6_port);
178# endif
179
180 default:
181 return 0;
182 }
183}
184//###########################################################################
185Netxx::socket_type Netxx::Peer::get_socketfd (void) const
186{
187 return socketfd_;
188}
189//###########################################################################
190Netxx::Peer::operator bool (void) const
191{
192 return okay_;
193}
194//###########################################################################
195const void* Netxx::Peer::get_sa (void) const
196{
197 return sockaddr_;
198}
199//###########################################################################
200Netxx::size_type Netxx::Peer::get_sa_size() const
201{
202 return sockaddr_size_;
203}
204//###########################################################################
205namespace Netxx
206{
207 //###########################################################################
208 std::ostream& operator<< (std::ostream &stream, const Peer &peer)
209 {
210const sockaddr *sa = reinterpret_cast<const sockaddr*>(peer.get_sa());
211
212if (peer) {
213 if (sa && sa->sa_family == AF_LOCAL) {
214if (peer.get_address()[0] == 0) stream << "domain socket";
215else stream << peer.get_address();
216 } else {
217stream << peer.get_address() << ":" << peer.get_port();
218 }
219}
220
221return stream;
222 }
223 //###########################################################################
224} // end Netxx namespace

Archive Download this file

Branches

Tags

Quick Links:     www.monotone.ca    -     Downloads    -     Documentation    -     Wiki    -     Code Forge    -     Build Status