#if HAVE_RECVMMSG
vector<struct mmsghdr> 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) {
struct Unit {
struct msghdr msgh;
struct iovec iov;
- char cbuf[256];
+ cmsgbuf_aligned cbuf;
};
vector<unique_ptr<Unit> > units;
int ret;
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<char*>(request), requestLen, &remote);
- addCMsgSrcAddr(&msgh, cbuf, &ss->sourceAddr, ss->sourceItf);
+ fillMSGHdr(&msgh, &iov, &cbuf, sizeof(cbuf), const_cast<char*>(request), requestLen, &remote);
+ addCMsgSrcAddr(&msgh, &cbuf, &ss->sourceAddr, ss->sourceItf);
result = sendmsg(sd, &msgh, 0);
}
}
#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<char*>(response), responseLen, const_cast<ComboAddress*>(&remote));
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;
{
char packet[4096];
/* used by HarvestDestinationAddress */
- char cbuf[256];
+ cmsgbuf_aligned cbuf;
ComboAddress remote;
ComboAddress dest;
struct iovec iov;
/* 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 */
continue;
}
- processUDPQuery(*cs, holders, msgh, remote, recvData[msgIdx].dest, recvData[msgIdx].packet, static_cast<uint16_t>(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<uint16_t>(got), sizeof(recvData[msgIdx].packet), outMsgVec.get(), &msgsToSend, &recvData[msgIdx].iov, &recvData[msgIdx].cbuf);
}
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);
struct msghdr msgh;
struct iovec iov;
- char cbuf[256];
+ cmsgbuf_aligned cbuf;
ComboAddress fromaddr;
for(;;) {
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<<Logger::Warning<<"dnsproxy.cc: Error sending reply with sendmsg (socket="<<i->second.outsock<<"): "<<strerror(errno)<<endl;
{
struct msghdr msgh;
struct iovec iov;
- char cbuf[256];
+ cmsgbuf_aligned cbuf;
/* Set up iov and msgh structures. */
memset(&msgh, 0, sizeof(struct msghdr));
msgh.msg_namelen = to.getSocklen();
if(from.sin4.sin_family) {
- addCMsgSrcAddr(&msgh, cbuf, &from, 0);
+ addCMsgSrcAddr(&msgh, &cbuf, &from, 0);
}
else {
msgh.msg_control=NULL;
// be careful: when using this for receive purposes, make sure addr->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;
{
struct msghdr msgh;
struct iovec iov;
- char cbuf[256];
+ cmsgbuf_aligned cbuf;
/* Set up iov and msgh structures. */
memset(&msgh, 0, sizeof(struct msghdr));
msgh.msg_flags = 0;
if (localItf != 0 && local) {
- addCMsgSrcAddr(&msgh, cbuf, local, localItf);
+ addCMsgSrcAddr(&msgh, &cbuf, local, localItf);
}
iov.iov_base = reinterpret_cast<void*>(const_cast<char*>(buffer));
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);
// 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;
};
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);
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<<Logger::Notice<<"Sending a packet to "<< p->getRemote() <<" ("<< buffer.length()<<" octets)"<<endl);
if(buffer.length() > p->getMaxReplyLen()) {
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<struct pollfd> rfds= d_rfds;
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<<Logger::Warning<<"Sending UDP reply to client "<<dc->getRemote()<<" failed with: "<<strerror(errno)<<endl;
ageDNSPacket(response, age);
struct msghdr msgh;
struct iovec iov;
- char cbuf[256];
- fillMSGHdr(&msgh, &iov, cbuf, 0, (char*)response.c_str(), response.length(), const_cast<ComboAddress*>(&fromaddr));
+ cmsgbuf_aligned cbuf;
+ fillMSGHdr(&msgh, &iov, &cbuf, 0, (char*)response.c_str(), response.length(), const_cast<ComboAddress*>(&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<<Logger::Warning<<"Sending UDP reply to client "<<source.toStringWithPort()<<(source != fromaddr ? " (via "+fromaddr.toStringWithPort()+")" : "")<<" failed with: "<<strerror(errno)<<endl;
ComboAddress fromaddr;
struct msghdr msgh;
struct iovec iov;
- char cbuf[256];
+ cmsgbuf_aligned cbuf;
bool firstQuery = true;
for(size_t queriesCounter = 0; queriesCounter < s_maxUDPQueriesPerRound; queriesCounter++) {
data.resize(maxIncomingQuerySize);
fromaddr.sin6.sin6_family=AF_INET6; // this makes sure fromaddr is big enough
- fillMSGHdr(&msgh, &iov, cbuf, sizeof(cbuf), &data[0], data.size(), &fromaddr);
+ fillMSGHdr(&msgh, &iov, &cbuf, sizeof(cbuf), &data[0], data.size(), &fromaddr);
if((len=recvmsg(fd, &msgh, 0)) >= 0) {