int AsyncUDPSocket::connect(const folly::SocketAddress& address) { CHECK_NE(-1, fd_) << "Socket not yet bound"; sockaddr_storage addrStorage; address.getAddress(&addrStorage); return fsp::connect( fd_, reinterpret_cast<sockaddr*>(&addrStorage), address.getActualSize()); }
SSLSessionCacheManager::SSLSessionCacheManager( uint32_t maxCacheSize, uint32_t cacheCullSize, SSLContext* ctx, const folly::SocketAddress& sockaddr, const string& context, EventBase* eventBase, SSLStats* stats, const std::shared_ptr<SSLCacheProvider>& externalCache): ctx_(ctx), stats_(stats), externalCache_(externalCache) { SSL_CTX* sslCtx = ctx->getSSLCtx(); SSLUtil::getSSLCtxExIndex(&sExDataIndex_); SSL_CTX_set_ex_data(sslCtx, sExDataIndex_, this); SSL_CTX_sess_set_new_cb(sslCtx, SSLSessionCacheManager::newSessionCallback); SSL_CTX_sess_set_get_cb(sslCtx, SSLSessionCacheManager::getSessionCallback); SSL_CTX_sess_set_remove_cb(sslCtx, SSLSessionCacheManager::removeSessionCallback); if (!FLAGS_dcache_unit_test && !context.empty()) { // Use the passed in context ctx->setSessionCacheContext(context); } SSL_CTX_set_session_cache_mode(sslCtx, SSL_SESS_CACHE_NO_INTERNAL | SSL_SESS_CACHE_SERVER); localCache_ = SSLSessionCacheManager::getLocalCache(maxCacheSize, cacheCullSize); VLOG(2) << "On VipID=" << sockaddr.describe() << " context=" << context; }
ssize_t AsyncUDPSocket::writev(const folly::SocketAddress& address, const struct iovec* vec, size_t iovec_len) { CHECK_NE(-1, fd_) << "Socket not yet bound"; sockaddr_storage addrStorage; address.getAddress(&addrStorage); struct msghdr msg; msg.msg_name = reinterpret_cast<void*>(&addrStorage); msg.msg_namelen = address.getActualSize(); msg.msg_iov = const_cast<struct iovec*>(vec); msg.msg_iovlen = iovec_len; msg.msg_control = nullptr; msg.msg_controllen = 0; msg.msg_flags = 0; return ::sendmsg(fd_, &msg, 0); }
void onDataAvailable(const folly::SocketAddress& client, size_t len, bool truncated) noexcept override { VLOG(4) << "Read " << len << " bytes (trun:" << truncated << ") from " << client.describe() << " - " << std::string(buf_, len); VLOG(4) << n_ << " left"; ++pongRecvd_; sendPing(); }
ssize_t AsyncUDPSocket::writev( const folly::SocketAddress& address, const struct iovec* vec, size_t iovec_len, int gso) { CHECK_NE(-1, fd_) << "Socket not yet bound"; sockaddr_storage addrStorage; address.getAddress(&addrStorage); struct msghdr msg; msg.msg_name = reinterpret_cast<void*>(&addrStorage); msg.msg_namelen = address.getActualSize(); msg.msg_iov = const_cast<struct iovec*>(vec); msg.msg_iovlen = iovec_len; msg.msg_control = nullptr; msg.msg_controllen = 0; msg.msg_flags = 0; #ifdef FOLLY_HAVE_MSG_ERRQUEUE if (gso > 0) { char control[CMSG_SPACE(sizeof(uint16_t))]; msg.msg_control = control; msg.msg_controllen = sizeof(control); struct cmsghdr* cm = CMSG_FIRSTHDR(&msg); cm->cmsg_level = SOL_UDP; cm->cmsg_type = UDP_SEGMENT; cm->cmsg_len = CMSG_LEN(sizeof(uint16_t)); uint16_t gso_len = static_cast<uint16_t>(gso); memcpy(CMSG_DATA(cm), &gso_len, sizeof(gso_len)); return sendmsg(fd_, &msg, 0); } #else CHECK_LT(gso, 1) << "GSO not supported"; #endif return sendmsg(fd_, &msg, 0); }
std::string MessagePrinter::serializeConnectionDetails( const folly::SocketAddress& from, const folly::SocketAddress& to, mc_protocol_t protocol) { std::string out; if (!from.empty()) { if (options_.script) { out.append( folly::sformat(",\n \"from\": \"{}\"", describeAddress(from))); } else { out.append(describeAddress(from)); } } if (!options_.script && (!from.empty() || !to.empty())) { out.append(" -> "); } if (!to.empty()) { if (options_.script) { out.append(folly::sformat(",\n \"to\": \"{}\"", describeAddress(to))); } else { out.append(describeAddress(to)); } } if ((!from.empty() || !to.empty()) && protocol != mc_unknown_protocol) { if (options_.script) { out.append(folly::sformat( ",\n \"protocol\": \"{}\"", mc_protocol_to_string(protocol))); } else { out.append(folly::sformat(" ({})", mc_protocol_to_string(protocol))); } } return out; }
void onDataAvailable(std::shared_ptr<folly::AsyncUDPSocket> /* socket */, const folly::SocketAddress& client, std::unique_ptr<folly::IOBuf> data, bool truncated) noexcept override { lastClient_ = client; lastMsg_ = data->moveToFbString().toStdString(); auto len = data->computeChainDataLength(); VLOG(4) << "Worker " << n_ << " read " << len << " bytes " << "(trun:" << truncated << ") from " << client.describe() << " - " << lastMsg_; sendPong(); }
std::string MessagePrinter::serializeConnectionDetails( const folly::SocketAddress& from, const folly::SocketAddress& to, mc_protocol_t protocol) { std::string out; if (!from.empty()) { out.append(from.describe()); } if (!from.empty() || !to.empty()) { out.append(" -> "); } if (!to.empty()) { out.append(to.describe()); } if ((!from.empty() || !to.empty()) && protocol != mc_unknown_protocol) { out.append(folly::sformat(" ({})", mc_protocol_to_string(protocol))); } return out; }
void AsyncUDPSocket::bind(const folly::SocketAddress& address) { int socket = fsp::socket(address.getFamily(), SOCK_DGRAM, IPPROTO_UDP); if (socket == -1) { throw AsyncSocketException( AsyncSocketException::NOT_OPEN, "error creating async udp socket", errno); } auto g = folly::makeGuard([&] { ::close(socket); }); // put the socket in non-blocking mode int ret = fcntl(socket, F_SETFL, O_NONBLOCK); if (ret != 0) { throw AsyncSocketException( AsyncSocketException::NOT_OPEN, "failed to put socket in non-blocking mode", errno); } if (reuseAddr_) { // put the socket in reuse mode int value = 1; if (setsockopt(socket, SOL_SOCKET, SO_REUSEADDR, &value, sizeof(value)) != 0) { throw AsyncSocketException( AsyncSocketException::NOT_OPEN, "failed to put socket in reuse mode", errno); } } if (reusePort_) { // put the socket in port reuse mode int value = 1; if (setsockopt(socket, SOL_SOCKET, SO_REUSEPORT, &value, sizeof(value)) != 0) { throw AsyncSocketException( AsyncSocketException::NOT_OPEN, "failed to put socket in reuse_port mode", errno); } } if (busyPollUs_ > 0) { #ifdef SO_BUSY_POLL // Set busy_poll time in microseconds on the socket. // It sets how long socket will be in busy_poll mode when no event occurs. int value = busyPollUs_; if (setsockopt(socket, SOL_SOCKET, SO_BUSY_POLL, &value, sizeof(value)) != 0) { throw AsyncSocketException( AsyncSocketException::NOT_OPEN, "failed to set SO_BUSY_POLL on the socket", errno); } #else /* SO_BUSY_POLL is not supported*/ throw AsyncSocketException( AsyncSocketException::NOT_OPEN, "SO_BUSY_POLL is not supported", errno); #endif } if (rcvBuf_ > 0) { // Set the size of the buffer for the received messages in rx_queues. int value = rcvBuf_; if (setsockopt(socket, SOL_SOCKET, SO_RCVBUF, &value, sizeof(value)) != 0) { throw AsyncSocketException( AsyncSocketException::NOT_OPEN, "failed to set SO_RCVBUF on the socket", errno); } } if (sndBuf_ > 0) { // Set the size of the buffer for the sent messages in tx_queues. int value = rcvBuf_; if (setsockopt(socket, SOL_SOCKET, SO_SNDBUF, &value, sizeof(value)) != 0) { throw AsyncSocketException( AsyncSocketException::NOT_OPEN, "failed to set SO_SNDBUF on the socket", errno); } } // If we're using IPv6, make sure we don't accept V4-mapped connections if (address.getFamily() == AF_INET6) { int flag = 1; if (setsockopt(socket, IPPROTO_IPV6, IPV6_V6ONLY, &flag, sizeof(flag))) { throw AsyncSocketException( AsyncSocketException::NOT_OPEN, "Failed to set IPV6_V6ONLY", errno); } } // bind to the address sockaddr_storage addrStorage; address.getAddress(&addrStorage); sockaddr* saddr = reinterpret_cast<sockaddr*>(&addrStorage); if (fsp::bind(socket, saddr, address.getActualSize()) != 0) { throw AsyncSocketException( AsyncSocketException::NOT_OPEN, "failed to bind the async udp socket for:" + address.describe(), errno); } // success g.dismiss(); fd_ = socket; ownership_ = FDOwnership::OWNS; // attach to EventHandler EventHandler::changeHandlerFD(fd_); if (address.getPort() != 0) { localAddress_ = address; } else { localAddress_.setFromLocalAddress(fd_); } }
void AsyncUDPSocket::bind(const folly::SocketAddress& address) { int socket = fsp::socket(address.getFamily(), SOCK_DGRAM, IPPROTO_UDP); if (socket == -1) { throw AsyncSocketException(AsyncSocketException::NOT_OPEN, "error creating async udp socket", errno); } auto g = folly::makeGuard([&] { ::close(socket); }); // put the socket in non-blocking mode int ret = fcntl(socket, F_SETFL, O_NONBLOCK); if (ret != 0) { throw AsyncSocketException(AsyncSocketException::NOT_OPEN, "failed to put socket in non-blocking mode", errno); } if (reuseAddr_) { // put the socket in reuse mode int value = 1; if (setsockopt(socket, SOL_SOCKET, SO_REUSEADDR, &value, sizeof(value)) != 0) { throw AsyncSocketException(AsyncSocketException::NOT_OPEN, "failed to put socket in reuse mode", errno); } } if (reusePort_) { // put the socket in port reuse mode int value = 1; if (setsockopt(socket, SOL_SOCKET, SO_REUSEPORT, &value, sizeof(value)) != 0) { throw AsyncSocketException(AsyncSocketException::NOT_OPEN, "failed to put socket in reuse_port mode", errno); } } // If we're using IPv6, make sure we don't accept V4-mapped connections if (address.getFamily() == AF_INET6) { int flag = 1; if (setsockopt(socket, IPPROTO_IPV6, IPV6_V6ONLY, &flag, sizeof(flag))) { throw AsyncSocketException( AsyncSocketException::NOT_OPEN, "Failed to set IPV6_V6ONLY", errno); } } // bind to the address sockaddr_storage addrStorage; address.getAddress(&addrStorage); sockaddr* saddr = reinterpret_cast<sockaddr*>(&addrStorage); if (fsp::bind(socket, saddr, address.getActualSize()) != 0) { throw AsyncSocketException( AsyncSocketException::NOT_OPEN, "failed to bind the async udp socket for:" + address.describe(), errno); } // success g.dismiss(); fd_ = socket; ownership_ = FDOwnership::OWNS; // attach to EventHandler EventHandler::changeHandlerFD(fd_); if (address.getPort() != 0) { localAddress_ = address; } else { localAddress_.setFromLocalAddress(fd_); } }