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