1 #include "hmbdc/Copyright.hpp" 3 #include "hmbdc/tips/rmcast/Transport.hpp" 4 #include "hmbdc/tips/udpcast/Transport.hpp" 5 #include "hmbdc/app/Logger.hpp" 6 #include "hmbdc/comm/inet/Endpoint.hpp" 7 #include "hmbdc//MetaUtils.hpp" 9 #include <boost/bind.hpp> 10 #include <boost/lexical_cast.hpp> 13 #include <type_traits> 15 namespace hmbdc {
namespace tips {
namespace rmcast {
17 namespace mcrecvtransport_detail {
25 template <
typename OutputBuffer,
typename Ep2SessionDict>
29 friend struct NetContext;
34 , Ep2SessionDict& sessionDict)
36 , cmdBuffer_(cmdBuffer)
39 , buf_(
new char[mtu_])
42 , subscriptions_(subscriptions)
43 , sessionDict_(sessionDict) {
45 if (setsockopt(mcFd_.fd, SOL_SOCKET,SO_REUSEADDR, &yes,
sizeof(yes)) < 0) {
46 HMBDC_LOG_C(
"failed to set reuse address errno=", errno);
48 auto sz = config_.
getExt<
int>(
"udpRecvBufferBytes");
50 if (setsockopt(mcFd_.fd, SOL_SOCKET, SO_RCVBUF, &sz,
sizeof(sz)) < 0) {
51 HMBDC_LOG_C(
"failed to set send buffer size=", sz);
57 , config_.
getExt<uint16_t>(
"mcastPort")).v;
58 if (::bind(mcFd_.fd, (
struct sockaddr *)&mcAddr,
sizeof(mcAddr)) < 0) {
59 HMBDC_THROW(std::runtime_error,
"failed to bind " 60 << config_.
getExt<std::string>(
"mcastAddr") <<
':' 61 << cfg.
getExt<
short>(
"mcastPort"));
65 mreq.imr_multiaddr.s_addr=inet_addr(config_.
getExt<std::string>(
"mcastAddr").c_str());
67 comm::inet::getLocalIpMatchMask(config_.
getExt<std::string>(
"ifaceAddr"));
68 mreq.imr_interface.s_addr=inet_addr(iface.c_str());
69 if (setsockopt(mcFd_.fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq,
sizeof(mreq)) < 0) {
70 HMBDC_THROW(std::runtime_error,
"failed to join " << config_.
getExt<std::string>(
"mcastAddr") <<
':' 71 << cfg.
getExt<
short>(
"mcastPort"));
82 hmbdc::app::utils::EpollTask::instance().add(
83 hmbdc::app::utils::EpollTask::EPOLLIN
84 | hmbdc::app::utils::EpollTask::EPOLLET, mcFd_);
98 if (hmbdc_unlikely(sendFrom_.sin_family != AF_INET)) {
101 if (hmbdc_likely(bytesRecved_)) {
105 while (bytesRecved_ >=
sizeof(TransportMessageHeader)) {
106 auto h =
reinterpret_cast<TransportMessageHeader*
>(bufCur_);
107 auto wireSize = h->wireSize();
108 if (hmbdc_likely(bytesRecved_ >= wireSize)) {
109 if (hmbdc_unlikely(h->typeTag() == TypeTagBackupSource::typeTag)) {
110 auto it = cmdBuffer_.claim();
112 size_t l = h->messagePayloadLen;
113 l = std::min(cmdBuffer_.maxItemSize(), l);
114 memcpy(b, h->payload(), l);
115 auto& bts = b->template get<TypeTagBackupSource>();
116 bts.sendFrom = sendFrom_;
117 cmdBuffer_.commit(it);
119 auto session = sessionDict_.find(sendFrom_);
120 if (hmbdc_unlikely(session != sessionDict_.end())) {
121 auto a = session->second->accept(h);
127 bytesRecved_ -= wireSize;
136 auto addrLen =
sizeof(sendFrom_);
137 if (mcFd_.isFdReady()) {
138 auto l = recvfrom(mcFd_.fd, buf_, mtu_, MSG_NOSIGNAL|MSG_DONTWAIT
139 , (sockaddr*)&sendFrom_, (socklen_t*)&addrLen);
140 if (hmbdc_unlikely(l < 0)) {
141 if (!mcFd_.checkErr()) {
142 HMBDC_LOG_C(
"recvmsg failed errno=", errno);
151 }
while(bytesRecved_);
155 sockaddr_in sendFrom_;
156 udpcast::EpollFd mcFd_;
160 TypeTagSet
const& HMBDC_RESTRICT subscriptions_;
161 Ep2SessionDict& HMBDC_RESTRICT sessionDict_;
164 template <
typename OutputBuffer,
typename Ep2SessionDict>
165 using McRecvTransport = mcrecvtransport_detail::McRecvTransport<OutputBuffer, Ep2SessionDict>;
T getExt(const path_type ¶m, bool throwIfMissing=true) const
get a value from the config
Definition: Config.hpp:238
Definition: MonoLockFreeBuffer.hpp:16
class to hold an hmbdc configuration
Definition: Config.hpp:44
impl class
Definition: McRecvTransport.hpp:26
Definition: Endpoint.hpp:17
void runOnce() HMBDC_RESTRICT
power the io_service and other things
Definition: McRecvTransport.hpp:91
Definition: Message.hpp:212
void start()
start the show by schedule the mesage recv
Definition: McRecvTransport.hpp:81
Definition: Transport.hpp:15