aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/netliba/socket/creators.cpp
diff options
context:
space:
mode:
authormonster <monster@ydb.tech>2022-07-07 14:41:37 +0300
committermonster <monster@ydb.tech>2022-07-07 14:41:37 +0300
commit06e5c21a835c0e923506c4ff27929f34e00761c2 (patch)
tree75efcbc6854ef9bd476eb8bf00cc5c900da436a2 /library/cpp/netliba/socket/creators.cpp
parent03f024c4412e3aa613bb543cf1660176320ba8f4 (diff)
downloadydb-06e5c21a835c0e923506c4ff27929f34e00761c2.tar.gz
fix ya.make
Diffstat (limited to 'library/cpp/netliba/socket/creators.cpp')
-rw-r--r--library/cpp/netliba/socket/creators.cpp141
1 files changed, 141 insertions, 0 deletions
diff --git a/library/cpp/netliba/socket/creators.cpp b/library/cpp/netliba/socket/creators.cpp
new file mode 100644
index 0000000000..3821bf55b9
--- /dev/null
+++ b/library/cpp/netliba/socket/creators.cpp
@@ -0,0 +1,141 @@
+#include "stdafx.h"
+#include <string.h>
+#include <util/generic/utility.h>
+#include <util/network/init.h>
+#include <util/system/defaults.h>
+#include <util/system/yassert.h>
+#include "socket.h"
+
+namespace NNetlibaSocket {
+ void* CreateTos(const ui8 tos, void* buffer) {
+#ifdef _win_
+ *(int*)buffer = (int)tos;
+#else
+ // glibc bug: http://sourceware.org/bugzilla/show_bug.cgi?id=13500
+ memset(buffer, 0, TOS_BUFFER_SIZE);
+
+ msghdr dummy;
+ Zero(dummy);
+ dummy.msg_control = buffer;
+ dummy.msg_controllen = TOS_BUFFER_SIZE;
+
+ // TODO: in FreeBSD setting TOS for dual stack sockets does not affect ipv4 frames
+ cmsghdr* cmsg = CMSG_FIRSTHDR(&dummy);
+ cmsg->cmsg_level = IPPROTO_IPV6;
+ cmsg->cmsg_type = IPV6_TCLASS;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(int));
+ memcpy(CMSG_DATA(cmsg), &tos, sizeof(tos)); // memcpy shut ups alias restrict warning
+
+ Y_ASSERT(CMSG_NXTHDR(&dummy, cmsg) == nullptr);
+#endif
+ return buffer;
+ }
+
+ TMsgHdr* AddSockAuxData(TMsgHdr* header, const ui8 tos, const sockaddr_in6& myAddr, void* buffer, size_t bufferSize) {
+#ifdef _win_
+ Y_UNUSED(header);
+ Y_UNUSED(tos);
+ Y_UNUSED(myAddr);
+ Y_UNUSED(buffer);
+ Y_UNUSED(bufferSize);
+ return nullptr;
+#else
+ header->msg_control = buffer;
+ header->msg_controllen = bufferSize;
+
+ size_t totalLen = 0;
+#ifdef _cygwin_
+ Y_UNUSED(tos);
+#else
+ // Cygwin does not support IPV6_TCLASS, so we ignore it
+ cmsghdr* cmsgTos = CMSG_FIRSTHDR(header);
+ if (cmsgTos == nullptr) {
+ header->msg_control = nullptr;
+ header->msg_controllen = 0;
+ return nullptr;
+ }
+ cmsgTos->cmsg_level = IPPROTO_IPV6;
+ cmsgTos->cmsg_type = IPV6_TCLASS;
+ cmsgTos->cmsg_len = CMSG_LEN(sizeof(int));
+ totalLen = CMSG_SPACE(sizeof(int));
+ *(ui8*)CMSG_DATA(cmsgTos) = tos;
+#endif
+
+ if (*(ui64*)myAddr.sin6_addr.s6_addr != 0u) {
+ in6_pktinfo* pktInfo;
+#ifdef _cygwin_
+ cmsghdr* cmsgAddr = CMSG_FIRSTHDR(header);
+#else
+ cmsghdr* cmsgAddr = CMSG_NXTHDR(header, cmsgTos);
+#endif
+ if (cmsgAddr == nullptr) {
+ // leave only previous record
+ header->msg_controllen = totalLen;
+ return nullptr;
+ }
+ cmsgAddr->cmsg_level = IPPROTO_IPV6;
+ cmsgAddr->cmsg_type = IPV6_PKTINFO;
+ cmsgAddr->cmsg_len = CMSG_LEN(sizeof(*pktInfo));
+ totalLen += CMSG_SPACE(sizeof(*pktInfo));
+ pktInfo = (in6_pktinfo*)CMSG_DATA(cmsgAddr);
+
+ pktInfo->ipi6_addr = myAddr.sin6_addr;
+ pktInfo->ipi6_ifindex = 0; /* 0 = use interface specified in routing table */
+ }
+ header->msg_controllen = totalLen; //write right len
+
+ return header;
+#endif
+ }
+
+ TIoVec CreateIoVec(char* data, const size_t dataSize) {
+ TIoVec result;
+ Zero(result);
+
+ result.iov_base = data;
+ result.iov_len = dataSize;
+
+ return result;
+ }
+
+ TMsgHdr CreateSendMsgHdr(const sockaddr_in6& addr, const TIoVec& iov, void* tosBuffer) {
+ TMsgHdr result;
+ Zero(result);
+
+ result.msg_name = (void*)&addr;
+ result.msg_namelen = sizeof(addr);
+ result.msg_iov = (TIoVec*)&iov;
+ result.msg_iovlen = 1;
+
+ if (tosBuffer) {
+#ifdef _win_
+ result.Tos = *(int*)tosBuffer;
+#else
+ result.msg_control = tosBuffer;
+ result.msg_controllen = TOS_BUFFER_SIZE;
+#endif
+ }
+
+ return result;
+ }
+
+ TMsgHdr CreateRecvMsgHdr(sockaddr_in6* addrBuf, const TIoVec& iov, void* controllBuffer) {
+ TMsgHdr result;
+ Zero(result);
+
+ Zero(*addrBuf);
+ result.msg_name = addrBuf;
+ result.msg_namelen = sizeof(*addrBuf);
+
+ result.msg_iov = (TIoVec*)&iov;
+ result.msg_iovlen = 1;
+#ifndef _win_
+ if (controllBuffer) {
+ memset(controllBuffer, 0, CTRL_BUFFER_SIZE);
+ result.msg_control = controllBuffer;
+ result.msg_controllen = CTRL_BUFFER_SIZE;
+ }
+#endif
+ return result;
+ }
+}