Line data Source code
1 : /* 2 : * Copyright (c) 2016 Juniper Networks, Inc. All rights reserved. 3 : */ 4 : 5 : /* 6 : * Implement a UNIX domain socket interface using boost::asio. 7 : */ 8 : #ifndef SRC_IO_USOCK_SERVER_H_ 9 : #define SRC_IO_USOCK_SERVER_H_ 10 : 11 : #include <cstdio> 12 : #include <iostream> 13 : #include <list> 14 : #include <string> 15 : #include <boost/array.hpp> 16 : #include <boost/bind/bind.hpp> 17 : #include <boost/enable_shared_from_this.hpp> 18 : #include <boost/shared_ptr.hpp> 19 : #include <boost/asio.hpp> 20 : #include <boost/function.hpp> 21 : 22 : using namespace boost::placeholders; 23 : 24 : #if defined(BOOST_ASIO_HAS_LOCAL_SOCKETS) 25 : 26 : class UnixDomainSocketSession : 27 : public boost::enable_shared_from_this<UnixDomainSocketSession> { 28 : public: 29 : static const int kPDULen = 4096; 30 : static const int kPDUHeaderLen = 4; 31 : static const int kPDUDataLen = 4092; 32 : 33 : enum Event { 34 : EVENT_NONE, 35 : READY, 36 : CLOSE 37 : }; 38 : 39 : typedef boost::function <void (UnixDomainSocketSession *, Event)> 40 : EventObserver; 41 : 42 2 : explicit UnixDomainSocketSession(boost::asio::io_context *io_service) 43 2 : : socket_(*io_service), session_id_(0) { 44 2 : } 45 : 46 : ~UnixDomainSocketSession(); 47 : 48 2 : boost::asio::local::stream_protocol::socket &socket() { 49 2 : return socket_; 50 : } 51 : 52 0 : void set_observer(EventObserver observer) { observer_ = observer; } 53 0 : uint64_t session_id() { return session_id_; } 54 1 : void set_session_id(uint64_t id) { session_id_ = id; } 55 : void Start(); 56 : void Send(const uint8_t * data, int data_len); 57 : 58 : private: 59 : typedef std::list <boost::asio::mutable_buffer> BufferQueue; 60 : 61 : void WriteToSocket(); 62 : void AppendBuffer(const uint8_t * data, int len); 63 : void DeleteBuffer(boost::asio::mutable_buffer); 64 : void HandleRead(const boost::system::error_code & error, size_t bytes); 65 : void HandleWrite(const boost::system::error_code & error); 66 : 67 : boost::asio::local::stream_protocol::socket socket_; 68 : BufferQueue buffer_queue_; 69 : uint8_t data_[kPDULen]; 70 : EventObserver observer_; 71 : uint64_t session_id_; 72 : }; 73 : 74 : typedef boost::shared_ptr <UnixDomainSocketSession> SessionPtr; 75 : 76 : class UnixDomainSocketServer { 77 : public: 78 : enum Event { 79 : EVENT_NONE, 80 : NEW_SESSION, 81 : DELETE_SESSION 82 : }; 83 : 84 : typedef boost::function <void (UnixDomainSocketServer *, 85 : UnixDomainSocketSession *, Event) > 86 : EventObserver; 87 : 88 : UnixDomainSocketServer(boost::asio::io_context *io_service, 89 : const std::string &file); 90 : 91 : void HandleAccept(SessionPtr new_session, 92 : const boost::system::error_code &error); 93 : 94 1 : void set_observer(EventObserver observer) { observer_ = observer; } 95 : 96 : private: 97 : boost::asio::io_context *io_service_; 98 : EventObserver observer_; 99 : boost::asio::local::stream_protocol::acceptor acceptor_; 100 : uint64_t session_idspace_; 101 : }; 102 : 103 : #else // defined(BOOST_ASIO_HAS_LOCAL_SOCKETS) 104 : #error Local sockets not available on this platform. 105 : #endif // defined(BOOST_ASIO_HAS_LOCAL_SOCKETS) 106 : 107 : #endif // SRC_IO_USOCK_SERVER_H_