From: Otto Moerbeek Date: Tue, 25 Jun 2019 12:27:00 +0000 (+0200) Subject: Align cmsg aux data, as recommended by OpenBSD manpage. X-Git-Tag: dnsdist-1.4.0-rc1~86^2~4 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7bec330a1148e4add77272e5ca49170ca3e54a17;p=thirdparty%2Fpdns.git Align cmsg aux data, as recommended by OpenBSD manpage. --- diff --git a/pdns/calidns.cc b/pdns/calidns.cc index 0f11e790fe..1d80ac81b9 100644 --- a/pdns/calidns.cc +++ b/pdns/calidns.cc @@ -71,11 +71,13 @@ static void* recvThread(const vector* sockets) #if HAVE_RECVMMSG vector buf(100); for(auto& m : buf) { - fillMSGHdr(&m.msg_hdr, new struct iovec, new char[512], 512, new char[1500], 1500, new ComboAddress("127.0.0.1")); + cmsgbuf_aligned *cbuf = new cmsgbuf_aligned; + fillMSGHdr(&m.msg_hdr, new struct iovec, cbuf, sizeof(*cbuf), new char[1500], 1500, new ComboAddress("127.0.0.1")); } #else struct msghdr buf; - fillMSGHdr(&buf, new struct iovec, new char[512], 512, new char[1500], 1500, new ComboAddress("127.0.0.1")); + cmsgbuf_aligned *cbuf = new cmsgbuf_aligned; + fillMSGHdr(&buf, new struct iovec, cbuf, sizeof(*cbuf), new char[1500], 1500, new ComboAddress("127.0.0.1")); #endif while(!g_done) { @@ -183,7 +185,7 @@ static void sendPackets(const vector* sockets, const vector > units; int ret; diff --git a/pdns/dnsdist.cc b/pdns/dnsdist.cc index d5c17029a9..dddcb79d8a 100644 --- a/pdns/dnsdist.cc +++ b/pdns/dnsdist.cc @@ -1224,10 +1224,10 @@ ssize_t udpClientSendRequestToBackend(const std::shared_ptr& ss else { struct msghdr msgh; struct iovec iov; - char cbuf[256]; + cmsgbuf_aligned cbuf; ComboAddress remote(ss->remote); - fillMSGHdr(&msgh, &iov, cbuf, sizeof(cbuf), const_cast(request), requestLen, &remote); - addCMsgSrcAddr(&msgh, cbuf, &ss->sourceAddr, ss->sourceItf); + fillMSGHdr(&msgh, &iov, &cbuf, sizeof(cbuf), const_cast(request), requestLen, &remote); + addCMsgSrcAddr(&msgh, &cbuf, &ss->sourceAddr, ss->sourceItf); result = sendmsg(sd, &msgh, 0); } @@ -1321,7 +1321,7 @@ bool checkQueryHeaders(const struct dnsheader* dh) } #if defined(HAVE_RECVMMSG) && defined(HAVE_SENDMMSG) && defined(MSG_WAITFORONE) -static void queueResponse(const ClientState& cs, const char* response, uint16_t responseLen, const ComboAddress& dest, const ComboAddress& remote, struct mmsghdr& outMsg, struct iovec* iov, char* cbuf) +static void queueResponse(const ClientState& cs, const char* response, uint16_t responseLen, const ComboAddress& dest, const ComboAddress& remote, struct mmsghdr& outMsg, struct iovec* iov, cbuf_aligned* cbuf) { outMsg.msg_len = 0; fillMSGHdr(&outMsg.msg_hdr, iov, nullptr, 0, const_cast(response), responseLen, const_cast(&remote)); @@ -1502,7 +1502,7 @@ ProcessQueryResult processQuery(DNSQuestion& dq, ClientState& cs, LocalHolders& return ProcessQueryResult::Drop; } -static void processUDPQuery(ClientState& cs, LocalHolders& holders, const struct msghdr* msgh, const ComboAddress& remote, ComboAddress& dest, char* query, uint16_t len, size_t queryBufferSize, struct mmsghdr* responsesVect, unsigned int* queuedResponses, struct iovec* respIOV, char* respCBuf) +static void processUDPQuery(ClientState& cs, LocalHolders& holders, const struct msghdr* msgh, const ComboAddress& remote, ComboAddress& dest, char* query, uint16_t len, size_t queryBufferSize, struct mmsghdr* responsesVect, unsigned int* queuedResponses, struct iovec* respIOV, cmsgbuf_aligned* respCBuf) { assert(responsesVect == nullptr || (queuedResponses != nullptr && respIOV != nullptr && respCBuf != nullptr)); uint16_t queryId = 0; @@ -1619,7 +1619,7 @@ static void MultipleMessagesUDPClientThread(ClientState* cs, LocalHolders& holde { char packet[4096]; /* used by HarvestDestinationAddress */ - char cbuf[256]; + cmsgbuf_aligned cbuf; ComboAddress remote; ComboAddress dest; struct iovec iov; @@ -1639,7 +1639,7 @@ static void MultipleMessagesUDPClientThread(ClientState* cs, LocalHolders& holde /* initialize the structures needed to receive our messages */ for (size_t idx = 0; idx < vectSize; idx++) { recvData[idx].remote.sin4.sin_family = cs->local.sin4.sin_family; - fillMSGHdr(&msgVec[idx].msg_hdr, &recvData[idx].iov, recvData[idx].cbuf, sizeof(recvData[idx].cbuf), recvData[idx].packet, s_udpIncomingBufferSize, &recvData[idx].remote); + fillMSGHdr(&msgVec[idx].msg_hdr, &recvData[idx].iov, &recvData[idx].cbuf, sizeof(recvData[idx].cbuf), recvData[idx].packet, s_udpIncomingBufferSize, &recvData[idx].remote); } /* go now */ @@ -1674,7 +1674,7 @@ static void MultipleMessagesUDPClientThread(ClientState* cs, LocalHolders& holde continue; } - processUDPQuery(*cs, holders, msgh, remote, recvData[msgIdx].dest, recvData[msgIdx].packet, static_cast(got), sizeof(recvData[msgIdx].packet), outMsgVec.get(), &msgsToSend, &recvData[msgIdx].iov, recvData[msgIdx].cbuf); + processUDPQuery(*cs, holders, msgh, remote, recvData[msgIdx].dest, recvData[msgIdx].packet, static_cast(got), sizeof(recvData[msgIdx].packet), outMsgVec.get(), &msgsToSend, &recvData[msgIdx].iov, &recvData[msgIdx].cbuf); } @@ -1718,12 +1718,12 @@ try struct msghdr msgh; struct iovec iov; /* used by HarvestDestinationAddress */ - char cbuf[256]; + cmsgbuf_aligned cbuf; ComboAddress remote; ComboAddress dest; remote.sin4.sin_family = cs->local.sin4.sin_family; - fillMSGHdr(&msgh, &iov, cbuf, sizeof(cbuf), packet, sizeof(packet), &remote); + fillMSGHdr(&msgh, &iov, &cbuf, sizeof(cbuf), packet, sizeof(packet), &remote); for(;;) { ssize_t got = recvmsg(cs->udpFD, &msgh, 0); diff --git a/pdns/dnsproxy.cc b/pdns/dnsproxy.cc index 69e5fd1b56..eafc6663ef 100644 --- a/pdns/dnsproxy.cc +++ b/pdns/dnsproxy.cc @@ -191,7 +191,7 @@ void DNSProxy::mainloop(void) struct msghdr msgh; struct iovec iov; - char cbuf[256]; + cmsgbuf_aligned cbuf; ComboAddress fromaddr; for(;;) { @@ -284,7 +284,7 @@ void DNSProxy::mainloop(void) msgh.msg_control=NULL; if(i->second.anyLocal) { - addCMsgSrcAddr(&msgh, cbuf, i->second.anyLocal.get_ptr(), 0); + addCMsgSrcAddr(&msgh, &cbuf, i->second.anyLocal.get_ptr(), 0); } if(sendmsg(i->second.outsock, &msgh, 0) < 0) g_log<sin4.sin_family is set appropriately so getSocklen works! // be careful: when using this function for *send* purposes, be sure to set cbufsize to 0! // be careful: if you don't call addCMsgSrcAddr after fillMSGHdr, make sure to set msg_control to NULL -void fillMSGHdr(struct msghdr* msgh, struct iovec* iov, char* cbuf, size_t cbufsize, char* data, size_t datalen, ComboAddress* addr) +void fillMSGHdr(struct msghdr* msgh, struct iovec* iov, cmsgbuf_aligned* cbuf, size_t cbufsize, char* data, size_t datalen, ComboAddress* addr) { iov->iov_base = data; iov->iov_len = datalen; @@ -294,7 +294,7 @@ size_t sendMsgWithOptions(int fd, const char* buffer, size_t len, const ComboAdd { struct msghdr msgh; struct iovec iov; - char cbuf[256]; + cmsgbuf_aligned cbuf; /* Set up iov and msgh structures. */ memset(&msgh, 0, sizeof(struct msghdr)); @@ -312,7 +312,7 @@ size_t sendMsgWithOptions(int fd, const char* buffer, size_t len, const ComboAdd msgh.msg_flags = 0; if (localItf != 0 && local) { - addCMsgSrcAddr(&msgh, cbuf, local, localItf); + addCMsgSrcAddr(&msgh, &cbuf, local, localItf); } iov.iov_base = reinterpret_cast(const_cast(buffer)); diff --git a/pdns/iputils.hh b/pdns/iputils.hh index 18d6e88194..d0b01adddb 100644 --- a/pdns/iputils.hh +++ b/pdns/iputils.hh @@ -1057,7 +1057,7 @@ void setSocketIgnorePMTU(int sockfd); bool IsAnyAddress(const ComboAddress& addr); bool HarvestDestinationAddress(const struct msghdr* msgh, ComboAddress* destination); bool HarvestTimestamp(struct msghdr* msgh, struct timeval* tv); -void fillMSGHdr(struct msghdr* msgh, struct iovec* iov, char* cbuf, size_t cbufsize, char* data, size_t datalen, ComboAddress* addr); +void fillMSGHdr(struct msghdr* msgh, struct iovec* iov, cmsgbuf_aligned* cbuf, size_t cbufsize, char* data, size_t datalen, ComboAddress* addr); ssize_t sendfromto(int sock, const char* data, size_t len, int flags, const ComboAddress& from, const ComboAddress& to); size_t sendMsgWithOptions(int fd, const char* buffer, size_t len, const ComboAddress* dest, const ComboAddress* local, unsigned int localItf, int flags); diff --git a/pdns/misc.cc b/pdns/misc.cc index 1f90bbcbd1..4aedbc11b7 100644 --- a/pdns/misc.cc +++ b/pdns/misc.cc @@ -884,7 +884,10 @@ Regex::Regex(const string &expr) // if you end up here because valgrind told you were are doing something wrong // with msgh->msg_controllen, please refer to https://github.com/PowerDNS/pdns/pull/3962 // first. -void addCMsgSrcAddr(struct msghdr* msgh, void* cmsgbuf, const ComboAddress* source, int itfIndex) +// Note that cmsgbuf should be aligned the same as a struct cmsghdr +// This can be achieved by declaring it as +// union { struct cmsghdr hdr; char buf[CMSG_SPACE(spaceneeded)]; } cmsgbuf; +void addCMsgSrcAddr(struct msghdr* msgh, cmsgbuf_aligned* cmsgbuf, const ComboAddress* source, int itfIndex) { struct cmsghdr *cmsg = NULL; diff --git a/pdns/misc.hh b/pdns/misc.hh index 205f033d2d..67472bd577 100644 --- a/pdns/misc.hh +++ b/pdns/misc.hh @@ -515,8 +515,11 @@ private: }; union ComboAddress; + +typedef union { struct cmsghdr hdr; char buf[256]; } cmsgbuf_aligned; + /* itfIndex is an interface index, as returned by if_nametoindex(). 0 means default. */ -void addCMsgSrcAddr(struct msghdr* msgh, void* cmsgbuf, const ComboAddress* source, int itfIndex); +void addCMsgSrcAddr(struct msghdr* msgh, cmsgbuf_aligned* cbuf, const ComboAddress* source, int itfIndex); unsigned int getFilenumLimit(bool hardOrSoft=0); void setFilenumLimit(unsigned int lim); diff --git a/pdns/nameserver.cc b/pdns/nameserver.cc index 5581239171..6044a44923 100644 --- a/pdns/nameserver.cc +++ b/pdns/nameserver.cc @@ -295,13 +295,13 @@ void UDPNameserver::send(DNSPacket *p) struct msghdr msgh; struct iovec iov; - char cbuf[256]; + cmsgbuf_aligned cbuf; - fillMSGHdr(&msgh, &iov, cbuf, 0, (char*)buffer.c_str(), buffer.length(), &p->d_remote); + fillMSGHdr(&msgh, &iov, &cbuf, 0, (char*)buffer.c_str(), buffer.length(), &p->d_remote); msgh.msg_control=NULL; if(p->d_anyLocal) { - addCMsgSrcAddr(&msgh, cbuf, p->d_anyLocal.get_ptr(), 0); + addCMsgSrcAddr(&msgh, &cbuf, p->d_anyLocal.get_ptr(), 0); } DLOG(g_log<getRemote() <<" ("<< buffer.length()<<" octets)"< p->getMaxReplyLen()) { @@ -320,10 +320,10 @@ DNSPacket *UDPNameserver::receive(DNSPacket *prefilled, std::string& buffer) struct msghdr msgh; struct iovec iov; - char cbuf[256]; + cmsgbuf_aligned cbuf; remote.sin6.sin6_family=AF_INET6; // make sure it is big enough - fillMSGHdr(&msgh, &iov, cbuf, sizeof(cbuf), &buffer.at(0), buffer.size(), &remote); + fillMSGHdr(&msgh, &iov, &cbuf, sizeof(cbuf), &buffer.at(0), buffer.size(), &remote); int err; vector rfds= d_rfds; diff --git a/pdns/pdns_recursor.cc b/pdns/pdns_recursor.cc index f2306c46fb..c4ffc17ba3 100644 --- a/pdns/pdns_recursor.cc +++ b/pdns/pdns_recursor.cc @@ -1654,12 +1654,12 @@ static void startDoResolve(void *p) if(!dc->d_tcp) { struct msghdr msgh; struct iovec iov; - char cbuf[256]; - fillMSGHdr(&msgh, &iov, cbuf, 0, (char*)&*packet.begin(), packet.size(), &dc->d_remote); + cmsgbuf_aligned cbuf; + fillMSGHdr(&msgh, &iov, &cbuf, 0, (char*)&*packet.begin(), packet.size(), &dc->d_remote); msgh.msg_control=NULL; if(g_fromtosockets.count(dc->d_socket)) { - addCMsgSrcAddr(&msgh, cbuf, &dc->d_local, 0); + addCMsgSrcAddr(&msgh, &cbuf, &dc->d_local, 0); } if(sendmsg(dc->d_socket, &msgh, 0) < 0 && g_logCommonErrors) g_log<getRemote()<<" failed with: "<(&fromaddr)); + cmsgbuf_aligned cbuf; + fillMSGHdr(&msgh, &iov, &cbuf, 0, (char*)response.c_str(), response.length(), const_cast(&fromaddr)); msgh.msg_control=NULL; if(g_fromtosockets.count(fd)) { - addCMsgSrcAddr(&msgh, cbuf, &destaddr, 0); + addCMsgSrcAddr(&msgh, &cbuf, &destaddr, 0); } if(sendmsg(fd, &msgh, 0) < 0 && g_logCommonErrors) g_log<= 0) {