From 86c3ac4a06bca4eefc94309047f531e83927f76e Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Tue, 5 Mar 2019 11:48:02 +0100 Subject: [PATCH] Only allocate the SSocket buffer when we actually need it, cleanup --- pdns/sstuff.hh | 85 ++++++++++++++++++++------------------------------ 1 file changed, 34 insertions(+), 51 deletions(-) diff --git a/pdns/sstuff.hh b/pdns/sstuff.hh index 403611eff..b8066b878 100644 --- a/pdns/sstuff.hh +++ b/pdns/sstuff.hh @@ -47,23 +47,17 @@ typedef int ProtocolType; //!< Supported protocol types //! Representation of a Socket and many of the Berkeley functions available class Socket : public boost::noncopyable { - Socket(int fd) + Socket(int fd): d_socket(fd) { - d_socket = fd; - d_buflen=4096; - d_buffer=new char[d_buflen]; } public: //! Construct a socket of specified address family and socket type. Socket(int af, int st, ProtocolType pt=0) { - if((d_socket=socket(af,st, pt))<0) + if((d_socket=socket(af, st, pt))<0) throw NetworkError(strerror(errno)); setCloseOnExec(d_socket); - - d_buflen=4096; - d_buffer=new char[d_buflen]; } ~Socket() @@ -73,17 +67,15 @@ public: } catch(const PDNSException& e) { } - - delete[] d_buffer; } //! If the socket is capable of doing so, this function will wait for a connection - Socket *accept() + std::unique_ptr accept() { struct sockaddr_in remote; socklen_t remlen=sizeof(remote); memset(&remote, 0, sizeof(remote)); - int s=::accept(d_socket,(sockaddr *)&remote, &remlen); + int s=::accept(d_socket, reinterpret_cast(&remote), &remlen); if(s<0) { if(errno==EAGAIN) return nullptr; @@ -91,21 +83,21 @@ public: throw NetworkError("Accepting a connection: "+string(strerror(errno))); } - return new Socket(s); + return std::unique_ptr(new Socket(s)); } //! Get remote address bool getRemote(ComboAddress &remote) { socklen_t remotelen=sizeof(remote); - return (getpeername(d_socket, (struct sockaddr *)&remote, &remotelen) >= 0); + return (getpeername(d_socket, reinterpret_cast(&remote), &remotelen) >= 0); } //! Check remote address against netmaskgroup ng - bool acl(NetmaskGroup &ng) + bool acl(const NetmaskGroup &ng) { ComboAddress remote; if (getRemote(remote)) - return ng.match((ComboAddress *) &remote); + return ng.match(remote); return false; } @@ -115,6 +107,7 @@ public: { ::setNonBlocking(d_socket); } + //! Set the socket to blocking void setBlocking() { @@ -125,7 +118,7 @@ public: { try { ::setReuseAddr(d_socket); - } catch (PDNSException &e) { + } catch (const PDNSException &e) { throw NetworkError(e.reason); } } @@ -134,26 +127,13 @@ public: void bind(const ComboAddress &local) { int tmp=1; - if(setsockopt(d_socket, SOL_SOCKET, SO_REUSEADDR,(char*)&tmp,sizeof tmp)<0) + if(setsockopt(d_socket, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast(&tmp), sizeof tmp)<0) throw NetworkError(string("Setsockopt failed: ")+strerror(errno)); - if(::bind(d_socket,(struct sockaddr *)&local, local.getSocklen())<0) + if(::bind(d_socket, reinterpret_cast(&local), local.getSocklen())<0) throw NetworkError("While binding: "+string(strerror(errno))); } -#if 0 - //! Bind the socket to a specified endpoint - void bind(const ComboAddress &ep) - { - ComboAddress local; - memset(reinterpret_cast(&local),0,sizeof(local)); - local.sin_family=d_family; - local.sin_addr.s_addr=ep.address.byte; - local.sin_port=htons(ep.port); - - bind(local); - } -#endif //! Connect the socket to a specified endpoint void connect(const ComboAddress &ep, int timeout=0) { @@ -167,20 +147,22 @@ public: \param ep Will be filled with the origin of the datagram */ void recvFrom(string &dgram, ComboAddress &ep) { - socklen_t remlen=sizeof(ep); + socklen_t remlen = sizeof(ep); ssize_t bytes; - if((bytes=recvfrom(d_socket, d_buffer, d_buflen, 0, (sockaddr *)&ep , &remlen)) <0) + d_buffer.resize(s_buflen); + if((bytes=recvfrom(d_socket, &d_buffer[0], s_buflen, 0, reinterpret_cast(&ep) , &remlen)) <0) throw NetworkError("After recvfrom: "+string(strerror(errno))); - dgram.assign(d_buffer,bytes); + dgram.assign(d_buffer, 0, static_cast(bytes)); } bool recvFromAsync(string &dgram, ComboAddress &ep) { struct sockaddr_in remote; - socklen_t remlen=sizeof(remote); + socklen_t remlen = sizeof(remote); ssize_t bytes; - if((bytes=recvfrom(d_socket, d_buffer, d_buflen, 0, (sockaddr *)&remote, &remlen))<0) { + d_buffer.resize(s_buflen); + if((bytes=recvfrom(d_socket, &d_buffer[0], s_buflen, 0, reinterpret_cast(&remote), &remlen))<0) { if(errno!=EAGAIN) { throw NetworkError("After async recvfrom: "+string(strerror(errno))); } @@ -188,7 +170,7 @@ public: return false; } } - dgram.assign(d_buffer,bytes); + dgram.assign(d_buffer, 0, static_cast(bytes)); return true; } @@ -196,7 +178,7 @@ public: //! For datagram sockets, send a datagram to a destination void sendTo(const char* msg, size_t len, const ComboAddress &ep) { - if(sendto(d_socket, msg, len, 0, (sockaddr *)&ep, ep.getSocklen())<0) + if(sendto(d_socket, msg, len, 0, reinterpret_cast(&ep), ep.getSocklen())<0) throw NetworkError("After sendto: "+string(strerror(errno))); } @@ -233,9 +215,9 @@ public: throw NetworkError("Writing to a socket: "+string(strerror(errno))); if(!res) throw NetworkError("EOF on socket"); - toWrite-=(size_t)res; - ptr+=(size_t)res; - }while(toWrite); + toWrite -= static_cast(res); + ptr += static_cast(res); + } while(toWrite); } @@ -275,7 +257,7 @@ public: void writenWithTimeout(const void *buffer, size_t n, int timeout) { size_t bytes=n; - const char *ptr = (char*)buffer; + const char *ptr = reinterpret_cast(buffer); ssize_t ret; while(bytes) { ret=::write(d_socket, ptr, bytes); @@ -295,8 +277,8 @@ public: throw NetworkError("Did not fulfill TCP write due to EOF"); } - ptr += (size_t) ret; - bytes -= (size_t) ret; + ptr += static_cast(ret); + bytes -= static_cast(ret); } } @@ -325,19 +307,20 @@ public: //! Reads a block of data from the socket to a string void read(string &data) { - ssize_t res=::recv(d_socket,d_buffer,d_buflen,0); + d_buffer.resize(s_buflen); + ssize_t res=::recv(d_socket, &d_buffer[0], s_buflen, 0); if(res<0) throw NetworkError("Reading from a socket: "+string(strerror(errno))); - data.assign(d_buffer,res); + data.assign(d_buffer, 0, static_cast(res)); } //! Reads a block of data from the socket to a block of memory size_t read(char *buffer, size_t bytes) { - ssize_t res=::recv(d_socket,buffer,bytes,0); + ssize_t res=::recv(d_socket, buffer, bytes, 0); if(res<0) throw NetworkError("Reading from a socket: "+string(strerror(errno))); - return (size_t) res; + return static_cast(res); } ssize_t readWithTimeout(char* buffer, size_t n, int timeout) @@ -366,9 +349,9 @@ public: } private: - char *d_buffer; + static const size_t s_buflen{4096}; + std::string d_buffer; int d_socket; - size_t d_buflen; }; -- 2.40.0