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);
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;
}
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;
}
}
-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));
remoteaddr.sun_family=AF_UNIX;
- strncpy(remoteaddr.sun_path, remote->c_str(), sizeof(remoteaddr.sun_path));
+ strncpy(remoteaddr.sun_path, remote->c_str(), sizeof(remoteaddr.sun_path)-1);
remoteaddr.sun_path[sizeof(remoteaddr.sun_path)-1] = '\0';
if(::sendto(d_fd, msg.c_str(), msg.length(), 0, (struct sockaddr*) &remoteaddr, sizeof(remoteaddr) ) < 0)