Branch data Line data Source code
1 : : /* 2 : : ** Copyright (C) 2023 Sylvain Fargier 3 : : ** 4 : : ** This software is provided 'as-is', without any express or implied 5 : : ** warranty. In no event will the authors be held liable for any damages 6 : : ** arising from the use of this software. 7 : : ** 8 : : ** Permission is granted to anyone to use this software for any purpose, 9 : : ** including commercial applications, and to alter it and redistribute it 10 : : ** freely, subject to the following restrictions: 11 : : ** 12 : : ** 1. The origin of this software must not be misrepresented; you must not 13 : : ** claim that you wrote the original software. If you use this software 14 : : ** in a product, an acknowledgment in the product documentation would be 15 : : ** appreciated but is not required. 16 : : ** 2. Altered source versions must be plainly marked as such, and must not be 17 : : ** misrepresented as being the original software. 18 : : ** 3. This notice may not be removed or altered from any source distribution. 19 : : ** 20 : : ** Created on: 2023-12-16T13:52:15 21 : : ** Author: Sylvain Fargier <fargier.sylvain@gmail.com> 22 : : */ 23 : : 24 : : #include "Socket.hpp" 25 : : 26 : : #include <arpa/inet.h> 27 : : 28 : : namespace ccut { 29 : : namespace net { 30 : : 31 : 15 : BaseSocket::BaseSocket(const std::string &name) : 32 : : ccut::Thread(name), 33 : 15 : m_socket{-1}, 34 : 15 : m_bufferSize{defaultBufferSize} 35 : 15 : {} 36 : : 37 : 14 : net::address_t BaseSocket::addr() const 38 : : { 39 : 14 : std::lock_guard<std::mutex> lock(m_mutex); 40 : 28 : return m_addr; 41 : 14 : } 42 : : 43 : 1 : void BaseSocket::setBufferSize(size_t size) 44 : : { 45 : 1 : std::lock_guard<std::mutex> lock(m_mutex); 46 : 1 : m_bufferSize = size; 47 : 1 : } 48 : : 49 : 1 : size_t BaseSocket::getBufferSize() const 50 : : { 51 : 1 : std::lock_guard<std::mutex> lock(m_mutex); 52 : 1 : return m_bufferSize; 53 : 1 : } 54 : : 55 : 24 : void BaseSocket::wake() 56 : : { 57 : 24 : m_wakePipe.write("X"); 58 : 24 : Thread::wake(); 59 : 24 : } 60 : : 61 : 9 : void BaseSocket::bind(uint16_t port, bool localhost) 62 : : { 63 : 9 : std::unique_lock<std::mutex> lock(m_mutex); 64 : 9 : if (m_socket >= 0) 65 : : { 66 : 0 : throw ccut::Exception(ccut::ErrorCode::Runtime, 67 : 0 : m_name + " already bound"); 68 : : } 69 : : 70 : 9 : m_socket = makeSocket(false); 71 : 9 : if (m_socket < 0) 72 : 1 : throw ccut::make_errno_exception(); 73 : : 74 : 16 : m_addr = net::address_t(AF_INET, 75 : 8 : localhost ? "127.0.0.1" : "255.255.255.255", port); 76 : 8 : if (::bind(m_socket, m_addr.addr(), m_addr.size()) < 0) 77 : : { 78 : 2 : ccut::Exception err = ccut::make_errno_exception(); 79 : 2 : m_addr = net::address_t(); 80 : 2 : ::close(m_socket); 81 : 2 : m_socket = -1; 82 : 2 : logger::error("ccut:net:socket") << "failed to bind: " << err.what(); 83 : 2 : throw err; 84 : 2 : } 85 : 6 : m_addr.detach(); 86 : 6 : socklen_t len = m_addr.size(); 87 : 6 : getsockname(m_socket, const_cast<sockaddr *>(m_addr.addr()), &len); 88 : 6 : lock.unlock(); 89 : 6 : wake(); 90 : 9 : } 91 : : 92 : 6 : void BaseSocket::bind6(uint16_t port, bool localhost) 93 : : { 94 : 6 : std::unique_lock<std::mutex> lock(m_mutex); 95 : 6 : if (m_socket >= 0) 96 : : { 97 : 0 : throw ccut::Exception(ccut::ErrorCode::Runtime, 98 : 0 : m_name + " already bound"); 99 : : } 100 : : 101 : 6 : m_socket = makeSocket(true); 102 : 5 : if (m_socket < 0) 103 : 1 : throw ccut::make_errno_exception(); 104 : : 105 : 4 : m_addr = net::address_t(AF_INET6, localhost ? "::1" : "::", port); 106 : 4 : if (::bind(m_socket, m_addr.addr(), m_addr.size()) < 0) 107 : : { 108 : 1 : ccut::Exception err = ccut::make_errno_exception(); 109 : 1 : m_addr = net::address_t(); 110 : 1 : ::close(m_socket); 111 : 1 : m_socket = -1; 112 : 1 : logger::error("ccut:net:socket") << "failed to bind: " << err.what(); 113 : 1 : throw err; 114 : 1 : } 115 : 3 : m_addr.detach(); 116 : 3 : socklen_t len = m_addr.size(); 117 : 3 : getsockname(m_socket, const_cast<sockaddr *>(m_addr.addr()), &len); 118 : 3 : lock.unlock(); 119 : 3 : wake(); 120 : 6 : } 121 : : 122 : : } // namespace net 123 : : } // namespace ccut