Serenity Operating System
at hosted 108 lines 4.4 kB view raw
1/* 2 * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.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 are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, this 9 * list of conditions and the following disclaimer. 10 * 11 * 2. Redistributions in binary form must reproduce the above copyright notice, 12 * this list of conditions and the following disclaimer in the documentation 13 * and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 21 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 22 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 23 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27#pragma once 28 29#include <AK/InlineLinkedList.h> 30#include <Kernel/DoubleBuffer.h> 31#include <Kernel/Net/Socket.h> 32 33namespace Kernel { 34 35class FileDescription; 36 37class LocalSocket final : public Socket 38 , public InlineLinkedListNode<LocalSocket> { 39 friend class InlineLinkedListNode<LocalSocket>; 40 41public: 42 static KResultOr<NonnullRefPtr<Socket>> create(int type); 43 virtual ~LocalSocket() override; 44 45 static void for_each(Function<void(LocalSocket&)>); 46 47 StringView socket_path() const; 48 String absolute_path(const FileDescription& description) const override; 49 50 // ^Socket 51 virtual KResult bind(const sockaddr*, socklen_t) override; 52 virtual KResult connect(FileDescription&, const sockaddr*, socklen_t, ShouldBlock = ShouldBlock::Yes) override; 53 virtual KResult listen(size_t) override; 54 virtual void get_local_address(sockaddr*, socklen_t*) override; 55 virtual void get_peer_address(sockaddr*, socklen_t*) override; 56 virtual void attach(FileDescription&) override; 57 virtual void detach(FileDescription&) override; 58 virtual bool can_read(const FileDescription&) const override; 59 virtual bool can_write(const FileDescription&) const override; 60 virtual ssize_t sendto(FileDescription&, const void*, size_t, int, const sockaddr*, socklen_t) override; 61 virtual ssize_t recvfrom(FileDescription&, void*, size_t, int flags, sockaddr*, socklen_t*) override; 62 virtual KResult getsockopt(FileDescription&, int level, int option, void*, socklen_t*) override; 63 virtual KResult chown(uid_t, gid_t) override; 64 virtual KResult chmod(mode_t) override; 65 66private: 67 explicit LocalSocket(int type); 68 virtual const char* class_name() const override { return "LocalSocket"; } 69 virtual bool is_local() const override { return true; } 70 bool has_attached_peer(const FileDescription&) const; 71 static Lockable<InlineLinkedList<LocalSocket>>& all_sockets(); 72 DoubleBuffer& receive_buffer_for(FileDescription&); 73 DoubleBuffer& send_buffer_for(FileDescription&); 74 75 // An open socket file on the filesystem. 76 RefPtr<FileDescription> m_file; 77 78 uid_t m_prebind_uid { 0 }; 79 gid_t m_prebind_gid { 0 }; 80 mode_t m_prebind_mode { 0 }; 81 82 // A single LocalSocket is shared between two file descriptions 83 // on the connect side and the accept side; so we need to store 84 // an additional role for the connect side and differentiate 85 // between them. 86 Role m_connect_side_role { Role::None }; 87 FileDescription* m_connect_side_fd { nullptr }; 88 89 virtual Role role(const FileDescription& description) const override 90 { 91 if (m_connect_side_fd == &description) 92 return m_connect_side_role; 93 return m_role; 94 } 95 96 bool m_bound { false }; 97 bool m_accept_side_fd_open { false }; 98 sockaddr_un m_address { 0, { 0 } }; 99 100 DoubleBuffer m_for_client; 101 DoubleBuffer m_for_server; 102 103 // for InlineLinkedList 104 LocalSocket* m_prev { nullptr }; 105 LocalSocket* m_next { nullptr }; 106}; 107 108}