1 // Socket.cpp - an IOChannel for sockets
3 // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
4 // Free Software Foundation, Inc
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 3 of the License, or
9 // (at your option) any later version.
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software
18 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 # include "gnashconfig.h"
31 #include "GnashSystemNetHeaders.h"
32 #include "GnashSystemFDHeaders.h"
35 #include "GnashAlgorithm.h"
36 #include "GnashSystemNetHeaders.h"
50 Socket::connected() const
63 while (retries
-- > 0) {
66 FD_SET(_socket
, &fdset
);
71 const int ret
= ::select(_socket
+ 1, nullptr, &fdset
, nullptr, &tval
);
74 if (ret
== 0) continue;
78 socklen_t len
= sizeof(val
);
79 // NB: the cast to char* is needed for windows and is harmless
81 if (::getsockopt(_socket
, SOL_SOCKET
, SO_ERROR
,
82 reinterpret_cast<char*>(&val
), &len
) < 0) {
83 log_debug("Socket Error");
96 // If interrupted by a system call, try again
98 const int err
= errno
;
100 log_debug("Socket interrupted by a system call");
104 log_error(_("XMLSocket: The socket was never available"));
116 if (_socket
) ::close(_socket
);
126 addrinfo
* getAddrInfo(const std::string
& hostname
, std::uint16_t port
)
128 addrinfo req
= addrinfo(), *ans
= nullptr;
130 req
.ai_family
= AF_UNSPEC
; // Allow IPv4 or IPv6
131 req
.ai_socktype
= SOCK_STREAM
;
133 std::string portNo
= std::to_string(port
);
134 int code
= getaddrinfo(hostname
.c_str(), portNo
.c_str(), &req
, &ans
);
136 log_error(_("getaddrinfo() failed with code: #%d - %s"),
137 code
, gai_strerror(code
));
147 Socket::connect(const std::string
& hostname
, std::uint16_t port
)
149 // We use _socket here because connected() or _connected might not
150 // be true if a connection attempt is underway but not completed.
152 log_error(_("Connection attempt while already connected"));
156 // If _socket is 0, either there has been no connection, or close() has
157 // been called. There must not be an error in either case.
160 if (hostname
.empty()) {
164 // This is used for ::connect()
165 std::unique_ptr
<addrinfo
, decltype(freeaddrinfo
)*> ans(getAddrInfo(hostname
, port
),
172 // display all the IP numbers
173 if (LogFile::getDefaultInstance().getVerbosity() != 0) {
174 for(const addrinfo
* ot
= ans
.get(); ot
; ot
= ot
->ai_next
) {
176 char clienthost
[INET6_ADDRSTRLEN
] = {};
177 int code
= getnameinfo(ot
->ai_addr
, ot
->ai_addrlen
,
178 clienthost
, sizeof(clienthost
),
179 nullptr, 0, NI_NUMERICHOST
);
182 log_error(_("getnameinfo() failed: %1%"), gai_strerror(code
));
184 log_debug("%s has address of: %s", hostname
, clienthost
);
189 // Multiple IPV$ and IPV6 numbers may be returned, so we try them all if
191 const addrinfo
*it
= ans
.get();
193 _socket
= ::socket(it
->ai_family
, it
->ai_socktype
, it
->ai_protocol
);
195 const int err
= errno
;
196 log_error(_("Socket creation failed: %s"), std::strerror(err
));
198 // Try the next IP number
206 log_error(_("Socket creation attempt(s) failed: giving up."));
212 const int flag
= ::fcntl(_socket
, F_GETFL
, 0);
213 ::fcntl(_socket
, F_SETFL
, flag
| O_NONBLOCK
);
216 // Attempt connection
217 int ret
= ::connect(_socket
, it
->ai_addr
, it
->ai_addrlen
);
219 const int err
= errno
;
221 if (err
!= EINPROGRESS
) {
222 log_error(_("Failed to connect to socket: %s"), std::strerror(err
));
231 // Magic timeout number. Use rcfile ?
232 const struct timeval tv
= { 120, 0 };
234 // NB: the cast to const char* is needed for windows and is harmless
236 if (::setsockopt(_socket
, SOL_SOCKET
, SO_RCVTIMEO
,
237 reinterpret_cast<const char*>(&tv
), sizeof(tv
))) {
238 log_error(_("Setting socket timeout failed"));
242 // NB: the cast to const char* is needed for windows and is harmless
244 ::setsockopt(_socket
, IPPROTO_TCP
, TCP_NODELAY
,
245 reinterpret_cast<const char*>(&on
), sizeof(on
));
255 // Read position is always _pos + _size wrapped.
256 const size_t cacheSize
= arraySize(_cache
);
257 size_t start
= (_pos
+ _size
) % cacheSize
;
259 char* startpos
= _cache
+ start
;
263 // The end pos is either the end of the cache or the first
265 char* endpos
= _cache
+ ((startpos
< _cache
+ _pos
) ?
268 const int thisRead
= endpos
- startpos
;
269 assert(thisRead
>= 0);
271 const int bytesRead
= ::recv(_socket
, startpos
, thisRead
, 0);
273 if (bytesRead
== -1) {
274 const int err
= errno
;
276 if (err
== EWOULDBLOCK
|| err
== EAGAIN
) {
277 // Nothing to read. Carry on.
281 log_error(_("Socket receive error %s"), std::strerror(err
));
289 // If there weren't enough bytes, that's it.
290 if (bytesRead
< thisRead
) break;
292 // If we wrote up to the end of the cache, try writing more to the
300 // Do a single read and report how many bytes were read.
302 Socket::read(void* dst
, std::streamsize num
)
305 if (num
< 0) return 0;
307 if (_size
< num
&& !_error
) {
311 if (_size
< num
) return 0;
312 return readNonBlocking(dst
, num
);
317 Socket::readNonBlocking(void* dst
, std::streamsize num
)
321 char* ptr
= static_cast<char*>(dst
);
323 if (!_size
&& !_error
) {
327 size_t cacheSize
= arraySize(_cache
);
329 // First read from pos to end
331 // Maximum bytes available to read.
332 const size_t canRead
= std::min
<size_t>(_size
, num
);
334 size_t toRead
= canRead
;
336 // Space to the end (for the first read).
337 const int thisRead
= std::min
<size_t>(canRead
, cacheSize
- _pos
);
339 std::copy(_cache
+ _pos
, _cache
+ _pos
+ thisRead
, ptr
);
345 std::copy(_cache
, _cache
+ toRead
, ptr
+ thisRead
);
351 return canRead
- toRead
;
355 Socket::write(const void* src
, std::streamsize num
)
360 const char* buf
= static_cast<const char*>(src
);
363 // Prevent sigpipe (which isn't a standard C signal)
364 // until leaving this function.
365 const struct SignalSetter
367 typedef void(*SigHandler
)(int);
368 SignalSetter() : _h(std::signal(SIGPIPE
, SIG_IGN
)) {}
369 ~SignalSetter() { std::signal(SIGPIPE
, _h
); }
375 // For broken pipe we prefer being notified with
376 // a return of -1 from ::send.
378 while (toWrite
> 0) {
379 int bytesSent
= ::send(_socket
, buf
, toWrite
, 0);
381 const int err
= errno
;
382 log_error(_("Socket send error %s"), std::strerror(err
));
387 if (!bytesSent
) break;
388 toWrite
-= bytesSent
;
391 return num
- toWrite
;
397 log_error(_("tell() called for Socket"));
398 return static_cast<std::streamsize
>(-1);
402 Socket::seek(std::streampos
)
404 log_error(_("seek() called for Socket"));
411 log_error(_("go_to_end() called for Socket"));
417 return !_size
&& bad();