diff options
| author | Christophe Fergeau <cfergeau@redhat.com> | 2014-11-21 11:01:17 +0100 |
|---|---|---|
| committer | Christophe Fergeau <cfergeau@redhat.com> | 2014-12-03 11:31:17 +0100 |
| commit | 1876971442ef808b5dcdaa5dc12df617f2179cb5 (patch) | |
| tree | 54cdeb35593396e8319ae079f900a18808fb201a /client/client_net_socket.cpp | |
| parent | b532ef0866cefe260ad0f08550f7c40d3580d0d7 (diff) | |
client: Remove client code
The client has been superseded by virt-viewer (
http://virt-manager.org/download/sources/virt-viewer/ ) and is no longer
being maintained.
Diffstat (limited to 'client/client_net_socket.cpp')
| -rw-r--r-- | client/client_net_socket.cpp | 388 |
1 files changed, 0 insertions, 388 deletions
diff --git a/client/client_net_socket.cpp b/client/client_net_socket.cpp deleted file mode 100644 index 9df68014..00000000 --- a/client/client_net_socket.cpp +++ /dev/null @@ -1,388 +0,0 @@ -/* - Copyright (C) 2009 Red Hat, Inc. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see <http://www.gnu.org/licenses/>. - - - Author: - yhalperi@redhat.com -*/ -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "common.h" -#include "client_net_socket.h" -#include "debug.h" -#include <spice/error_codes.h> -#include "utils.h" - -ClientNetSocket::ClientNetSocket(uint16_t id, const struct in_addr& dst_addr, uint16_t dst_port, - ProcessLoop& process_loop, EventHandler& event_handler) - : _id (id) - , _local_addr (dst_addr) - , _local_port (dst_port) - , _peer (INVALID_SOCKET) - , _process_loop (process_loop) - , _event_handler (event_handler) - , _num_recv_tokens (0) - , _send_message (NULL) - , _send_pos (0) - , _status (SOCKET_STATUS_CLOSED) - , _fin_pending (false) - , _close_pending (false) -{ -} - -ClientNetSocket::~ClientNetSocket() -{ - close(); -} - -bool ClientNetSocket::connect(uint32_t recv_tokens) -{ - struct sockaddr_in addr; - int no_delay; - - - ASSERT(_peer == INVALID_SOCKET && _status == SOCKET_STATUS_CLOSED); - - addr.sin_port = _local_port; - addr.sin_addr.s_addr = _local_addr.s_addr; - addr.sin_family = AF_INET; - - if ((_peer = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) { - int err = sock_error(); - THROW("%s: failed to create socket: %s", __FUNCTION__, sock_err_message(err)); - } - - no_delay = 1; - if (setsockopt(_peer, IPPROTO_TCP, TCP_NODELAY, - (const char*)&no_delay, sizeof(no_delay)) == SOCKET_ERROR) { - LOG_WARN("set TCP_NODELAY failed"); - } - - LOG_INFO("connect to ip=%s port=%d (connection_id=%d)", - inet_ntoa(addr.sin_addr), ntohs(addr.sin_port), _id); - - if (::connect(_peer, (struct sockaddr*)&addr, sizeof(sockaddr_in)) == SOCKET_ERROR) { - int err = sock_error(); - closesocket(_peer); - _peer = INVALID_SOCKET; - LOG_INFO("connect to ip=%s port=%d failed %s (connection_id=%d)", - inet_ntoa(addr.sin_addr), ntohs(addr.sin_port), sock_err_message(err), _id); - return false; - } - - _process_loop.add_socket(*this); - _status = SOCKET_STATUS_OPEN; - _num_recv_tokens = recv_tokens; - return true; -} - -void ClientNetSocket::push_disconnect() -{ - if ((_status == SOCKET_STATUS_CLOSED) || _close_pending) { - THROW("%s: disconnect attempt for disconnected socket %s %d", __FUNCTION__, - inet_ntoa(_local_addr), ntohs(_local_port)); - } - - _close_pending = true; - - if (!during_send()) { - close_and_tell(); - } -} - -void ClientNetSocket::push_fin() -{ - if ((_status == SOCKET_STATUS_OPEN) || (_status == SOCKET_STATUS_RECEIVED_FIN)) { - _fin_pending = true; - if (!during_send()) { - try { - apply_guest_fin(); - } catch (ClientNetSocket::ShutdownExcpetion&) { - close_and_tell(); - } - } - } else { - THROW("%s: unexpected fin connection_id=%d (status=%d)", __FUNCTION__, - _id, _status); - } -} - -void ClientNetSocket::add_recv_tokens(uint32_t num_tokens) -{ - if ((_status == SOCKET_STATUS_CLOSED) || _close_pending) { - THROW("%s: ack attempt for disconnected socket connection_id=%d", __FUNCTION__, - _id); - } - - _num_recv_tokens += num_tokens; - - // recv might have not been called because tokens weren't available - if (_num_recv_tokens && (_num_recv_tokens == num_tokens)) { - if (can_receive()) { - receive(); - } - } -} - -void ClientNetSocket::push_send(SendBuffer& buf) -{ - if (!can_send()) { - THROW("%s: unexpected send attempt for connection_id=%d (status = %d)", - __FUNCTION__, _id, _status); - } - - if (_fin_pending || _close_pending) { - THROW("%s: unexpected send attempt for connection_id=%d - shutdown send pending", - __FUNCTION__, _id); - } - - _send_messages.push_back(buf.ref()); - send(); -} - -void ClientNetSocket::on_event() -{ - if (can_send()) { - send(); - } - - if (!during_send()) { - if (_close_pending) { - close_and_tell(); - } else if (_fin_pending) { - apply_guest_fin(); - } - } - - if (can_receive()) { - receive(); - } -} - -void ClientNetSocket::apply_guest_fin() -{ - if (_status == SOCKET_STATUS_OPEN) { - if (shutdown(_peer, SHUT_WR) == SOCKET_ERROR) { - int err = sock_error(); - LOG_INFO("shutdown in connection_id=%d failed %s", _id, sock_err_message(err)); - throw ClientNetSocket::ShutdownExcpetion(); - } - - _fin_pending = false; - _status = SOCKET_STATUS_SENT_FIN; - } else if (_status == SOCKET_STATUS_RECEIVED_FIN) { - close_and_tell(); - } -} - -void ClientNetSocket::handle_client_fin() -{ - if (_status == SOCKET_STATUS_OPEN) { - _status = SOCKET_STATUS_RECEIVED_FIN; - _event_handler.on_socket_fin_recv(*this); - } else if (_status == SOCKET_STATUS_SENT_FIN) { - close_and_tell(); - } -} - -inline bool ClientNetSocket::during_send() -{ - return ((!_send_messages.empty()) || _send_message); -} - -inline bool ClientNetSocket::can_send() -{ - return ((_status == SOCKET_STATUS_OPEN) || (_status == SOCKET_STATUS_RECEIVED_FIN)); -} - -inline bool ClientNetSocket::can_receive() -{ - return ((_status == SOCKET_STATUS_OPEN) || (_status == SOCKET_STATUS_SENT_FIN)); -} - -void ClientNetSocket::send_message_done() -{ - _send_message->unref(); - _send_message = NULL; - _send_pos = 0; - _event_handler.on_socket_message_send_done(*this); -} - -void ClientNetSocket::send() -{ - ASSERT(_peer != INVALID_SOCKET); - try { - if (_send_message) { - _send_pos += send_buf(_send_message->data() + _send_pos, - _send_message->size() - _send_pos); - - if (_send_pos != _send_message->size()) { - return; - } else { - send_message_done(); - } - } - - while (!_send_messages.empty()) { - _send_message = _send_messages.front(); - _send_messages.pop_front(); - _send_pos = send_buf(_send_message->data(), _send_message->size()); - if (_send_pos != _send_message->size()) { - return; - } else { - send_message_done(); - } - } - } catch (ClientNetSocket::SendException&) { - close_and_tell(); - } -} - -uint32_t ClientNetSocket::send_buf(const uint8_t* buf, uint32_t size) -{ - const uint8_t* pos = buf; - ASSERT(_peer != INVALID_SOCKET); - while (size) { - int now; - if ((now = ::send(_peer, (char*)pos, size, MSG_NOSIGNAL)) == SOCKET_ERROR) { - int err = sock_error(); - if (err == WOULDBLOCK_ERR) { - break; - } - - if (err == INTERRUPTED_ERR) { - continue; - } - - LOG_INFO("send in connection_id=%d failed %s", _id, sock_err_message(err)); - throw ClientNetSocket::SendException(); - } - size -= now; - pos += now; - } - return pos - buf; -} - -void ClientNetSocket::receive() -{ - ASSERT(_peer != INVALID_SOCKET); - bool shutdown; - while (_num_recv_tokens) { - ReceiveBuffer& rcv_buf = alloc_receive_buffer(); - uint32_t size; - - try { - size = receive_buf(rcv_buf.buf(), rcv_buf.buf_max_size(), shutdown); - } catch (ClientNetSocket::ReceiveException&) { - rcv_buf.release_buf(); - close_and_tell(); - return; - } - - if (size) { - rcv_buf.set_buf_size(size); - _num_recv_tokens--; - _event_handler.on_socket_message_recv_done(*this, rcv_buf); - } else { - rcv_buf.release_buf(); - } - - if (shutdown) { - handle_client_fin(); - return; - } - - if (size < rcv_buf.buf_max_size()) { - return; - } - } -} - -uint32_t ClientNetSocket::receive_buf(uint8_t* buf, uint32_t max_size, bool& shutdown) -{ - uint8_t* pos = buf; - ASSERT(_peer != INVALID_SOCKET); - - shutdown = false; - - while (max_size) { - int now; - if ((now = ::recv(_peer, (char*)pos, max_size, 0)) <= 0) { - if (now == 0) { - shutdown = true; - break; // a case where fin is received, but before that, there is a msg - } - - int err = sock_error(); - - if (err == WOULDBLOCK_ERR) { - break; - } - - if (err == INTERRUPTED_ERR) { - continue; - } - - LOG_INFO("receive in connection_id=%d failed errno=%s", _id, sock_err_message(err)); - throw ClientNetSocket::ReceiveException(); - } - max_size -= now; - pos += now; - } - - return (pos - buf); -} - -void ClientNetSocket::release_wait_send_messages() -{ - if (_send_message) { - _send_message->unref(); - _send_message = NULL; - _send_pos = 0; - } - - while (!_send_messages.empty()) { - _send_messages.front()->unref(); - _send_messages.pop_front(); - } -} - -void ClientNetSocket::close() -{ - release_wait_send_messages(); - apply_disconnect(); -} - -void ClientNetSocket::close_and_tell() -{ - close(); - _event_handler.on_socket_disconnect(*this); -} - -void ClientNetSocket::apply_disconnect() -{ - if (_peer != INVALID_SOCKET) { - _process_loop.remove_socket(*this); - closesocket(_peer); - _peer = INVALID_SOCKET; - LOG_INFO("closing connection_id=%d", _id); - } - _status = SOCKET_STATUS_CLOSED; - _close_pending = false; - _fin_pending = false; -} |
