monotone

monotone Mtn Source Tree

Root/netxx/streambase.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::StreamBase class
35 * along with some helper functions.
36**/
37
38// common header
39#include "common.h"
40
41// Netxx includes
42#include "netxx/streambase.h"
43#include "netxx/sockopt.h"
44#include "netxx/address.h"
45#include "netxx/peer.h"
46#include "netxx/types.h"
47#include "socket.h"
48
49// standard includes
50#include <cstring>
51#include <algorithm>
52
53//####################################################################
54namespace
55{
56 bool client_connect (Netxx::Socket &socket, const Netxx::Peer &peer,
57 const Netxx::Timeout &timeout, std::string &message);
58}
59//####################################################################
60Netxx::StreamBase::StreamBase (const Timeout &timeout)
61 : timeout_(timeout)
62{ }
63//####################################################################
64Netxx::StreamBase::~StreamBase (void)
65{ }
66//####################################################################
67void Netxx::StreamBase::make_connection (Socket &socket, const Address &address)
68{
69 std::string message;
70
71 // connect this socket to the given address
72 Address::const_iterator ai(address.begin()), aend(address.end());
73
74 // make sure there is at least one network address
75 if (ai == aend) throw Exception("no address to connect to");
76
77 // try all addresses
78 bool connected = false;
79 for (; ai != aend; ++ai) {
80if (client_connect(socket, *ai, timeout_, message)) {
81 connected = true;
82 break;
83}
84 }
85
86 // make sure we got connected
87 if (!connected) {
88std::string error("failed to connect: ");
89error += message;
90throw NetworkException(error);
91 }
92}
93//####################################################################
94void Netxx::StreamBase::swap_base (StreamBase &other)
95{
96 std::swap(timeout_, other.timeout_);
97}
98//####################################################################
99void Netxx::StreamBase::set_timeout (const Timeout &timeout)
100{
101 timeout_ = timeout;
102}
103//####################################################################
104const Netxx::Timeout& Netxx::StreamBase::get_timeout (void) const
105{
106 return timeout_;
107}
108//####################################################################
109namespace
110{
111 //####################################################################
112 bool client_connect (Netxx::Socket &socket, const Netxx::Peer &peer,
113 const Netxx::Timeout &timeout, std::string &message)
114 {
115const sockaddr *sa = static_cast<const sockaddr*>(peer.get_sa());
116Netxx::size_type sa_size = peer.get_sa_size();
117
118/*
119 * Get the socket type for this Peer
120 */
121Netxx::Socket::Type stype;
122switch (sa->sa_family) {
123 case AF_INET:
124stype = Netxx::Socket::TCP;
125break;
126
127
128#ifndef NETXX_NO_INET6
129 case AF_INET6:
130stype = Netxx::Socket::TCP6;
131break;
132#endif
133
134#ifndef WIN32
135 case AF_LOCAL:
136stype = Netxx::Socket::LOCALSTREAM;
137break;
138#endif
139
140 default:
141stype = Netxx::Socket::TCP;
142}
143
144/*
145 * Create a tmp socket so that the Socket class will do all the hard
146 * work for us. Then replace the socket given in the param list with
147 * the tmp socket.
148 */
149Netxx::Socket tmp_socket(stype);
150tmp_socket.swap(socket);
151
152Netxx::socket_type socketfd=socket.get_socketfd();
153Netxx::SockOpt socket_options(socketfd, true);
154if (timeout) socket_options.set_non_blocking();
155
156if (connect(socketfd, sa, sa_size) != 0) {
157 Netxx::error_type error_code = Netxx::get_last_error();
158
159 if (error_code == EINPROGRESS || error_code == EWOULDBLOCK || error_code == EINTR) {
160if (!socket.readable_or_writable(timeout)) {
161 message = "connection timed out";
162 return false;
163}
164
165return socket_options.check_for_error(message);
166 }
167
168 message = Netxx::str_error(error_code);
169 return false;
170}
171
172return true;
173 }
174 //####################################################################
175} // end anonymous namespace

Archive Download this file

Branches

Tags

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