]> git.ipfire.org Git - thirdparty/pdns.git/blobdiff - pdns/rec_channel.cc
Merge pull request #8223 from PowerDNS/omoerbeek-patch-1
[thirdparty/pdns.git] / pdns / rec_channel.cc
index 2bbb54c1a3d50fbbe2b7bb1ea9d65c9f548bbf29..ccfd766cb8925b02d65212062431c6bbdd6a8047 100644 (file)
@@ -32,6 +32,32 @@ RecursorControlChannel::~RecursorControlChannel()
     unlink(d_local.sun_path);
 }
 
+static void setSocketBuffer(int fd, int optname, uint32_t size)
+{
+  uint32_t psize=0;
+  socklen_t len=sizeof(psize);
+
+  if (getsockopt(fd, SOL_SOCKET, optname, (void*)&psize, &len))
+    throw PDNSException("Unable to getsocket buffer size: "+stringerror());
+
+  if (psize > size)
+    return;
+  
+  // failure to raise is not fatal
+  setsockopt(fd, SOL_SOCKET, optname, (const void*)&size, sizeof(size));
+}
+
+
+static void setSocketReceiveBuffer(int fd, uint32_t size)
+{
+  setSocketBuffer(fd, SO_RCVBUF, size);
+}
+
+static void setSocketSendBuffer(int fd, uint32_t size)
+{
+  setSocketBuffer(fd, SO_SNDBUF, size);
+}
+
 int RecursorControlChannel::listen(const string& fname)
 {
   d_fd=socket(AF_UNIX,SOCK_DGRAM,0);
@@ -54,6 +80,10 @@ int RecursorControlChannel::listen(const string& fname)
   if(bind(d_fd, (sockaddr*)&d_local,sizeof(d_local))<0) 
     throw PDNSException("Unable to bind to controlsocket '"+fname+"': "+stringerror());
 
+  // receive buf should be size of max datagram plus address size
+  setSocketReceiveBuffer(d_fd, 60 * 1024);
+  setSocketSendBuffer(d_fd, 64 * 1024);
+  
   return d_fd;
 }
 
@@ -100,6 +130,10 @@ void RecursorControlChannel::connect(const string& path, const string& fname)
       throw PDNSException("Unable to connect to remote '"+string(remote.sun_path)+"': "+stringerror());
     }
 
+    // receive buf should be size of max datagram plus address size
+    setSocketReceiveBuffer(d_fd, 60 * 1024);
+    setSocketSendBuffer(d_fd, 64 * 1024);
+
   } catch (...) {
     close(d_fd);
     d_fd=-1;
@@ -108,8 +142,16 @@ void RecursorControlChannel::connect(const string& path, const string& fname)
   }
 }
 
-void RecursorControlChannel::send(const std::string& msg, const std::string* remote)
+void RecursorControlChannel::send(const std::string& msg, const std::string* remote, unsigned int timeout)
 {
+  int ret = waitForRWData(d_fd, false, timeout, 0);
+  if(ret == 0) {
+    throw PDNSException("Timeout sending message over control channel");
+  }
+  else if(ret < 0) {
+    throw PDNSException("Error sending message over control channel:" + string(strerror(errno)));
+  }
+
   if(remote) {
     struct sockaddr_un remoteaddr;
     memset(&remoteaddr, 0, sizeof(remoteaddr));