Use sockaddr_union instead of sockaddr_storage.

pull/2/head
Tatsuhiro Tsujikawa 2011-10-20 00:06:44 +09:00
parent c01c34f24a
commit 9b4855a5f0
4 changed files with 54 additions and 71 deletions

View File

@ -229,14 +229,12 @@ void BtSetup::setup(std::vector<Command*>& commands,
initialized = true; initialized = true;
} }
} else { } else {
std::vector<std::pair<sockaddr_storage, socklen_t> > ifAddrs; std::vector<std::pair<sockaddr_union, socklen_t> > ifAddrs;
getInterfaceAddress(ifAddrs, lpdInterface, AF_INET, AI_NUMERICHOST); getInterfaceAddress(ifAddrs, lpdInterface, AF_INET, AI_NUMERICHOST);
for(std::vector<std::pair<sockaddr_storage, socklen_t> >::const_iterator for(std::vector<std::pair<sockaddr_union, socklen_t> >::const_iterator
i = ifAddrs.begin(), eoi = ifAddrs.end(); i != eoi; ++i) { i = ifAddrs.begin(), eoi = ifAddrs.end(); i != eoi; ++i) {
sockaddr_in addr;
memcpy(&addr, &(*i).first, (*i).second);
char host[NI_MAXHOST]; char host[NI_MAXHOST];
if(inetNtop(AF_INET, &addr.sin_addr, host, sizeof(host)) == 0 && if(inetNtop(AF_INET, &(*i).first.in, host, sizeof(host)) == 0 &&
receiver->init(host)) { receiver->init(host)) {
initialized = true; initialized = true;
break; break;

View File

@ -221,21 +221,20 @@ SharedHandle<SocketCore> FtpConnection::createServerSocket()
bool FtpConnection::sendEprt(const SharedHandle<SocketCore>& serverSocket) bool FtpConnection::sendEprt(const SharedHandle<SocketCore>& serverSocket)
{ {
if(socketBuffer_.sendBufferIsEmpty()) { if(socketBuffer_.sendBufferIsEmpty()) {
struct sockaddr_storage sockaddr; sockaddr_union sockaddr;
socklen_t len = sizeof(sockaddr); socklen_t len = sizeof(sockaddr);
serverSocket->getAddrInfo(sockaddr, len); serverSocket->getAddrInfo(sockaddr, len);
std::pair<std::string, uint16_t> addrinfo = util::getNumericNameInfo std::pair<std::string, uint16_t> addrinfo =
(reinterpret_cast<const struct sockaddr*>(&sockaddr), len); util::getNumericNameInfo(&sockaddr.sa, len);
std::string request = "EPRT "; std::string request = "EPRT ";
request += "|"; request += "|";
request += util::itos(sockaddr.ss_family == AF_INET?1:2); request += util::itos(sockaddr.storage.ss_family == AF_INET ? 1 : 2);
request += "|"; request += "|";
request += addrinfo.first; request += addrinfo.first;
request += "|"; request += "|";
request += util::uitos(addrinfo.second); request += util::uitos(addrinfo.second);
request += "|\r\n"; request += "|\r\n";
A2_LOG_INFO(fmt(MSG_SENDING_REQUEST, A2_LOG_INFO(fmt(MSG_SENDING_REQUEST, cuid_, request.c_str()));
cuid_, request.c_str()));
socketBuffer_.pushStr(request); socketBuffer_.pushStr(request);
} }
socketBuffer_.send(); socketBuffer_.send();

View File

@ -118,7 +118,7 @@ std::string errorMsg(int errNum)
int SocketCore::protocolFamily_ = AF_UNSPEC; int SocketCore::protocolFamily_ = AF_UNSPEC;
std::vector<std::pair<struct sockaddr_storage, socklen_t> > std::vector<std::pair<sockaddr_union, socklen_t> >
SocketCore::bindAddrs_; SocketCore::bindAddrs_;
#ifdef ENABLE_SSL #ifdef ENABLE_SSL
@ -280,14 +280,12 @@ void SocketCore::bind
sockfd_ = fd; sockfd_ = fd;
} }
} else { } else {
for(std::vector<std::pair<struct sockaddr_storage, socklen_t> >:: for(std::vector<std::pair<sockaddr_union, socklen_t> >::
const_iterator i = bindAddrs_.begin(), eoi = bindAddrs_.end(); const_iterator i = bindAddrs_.begin(), eoi = bindAddrs_.end();
i != eoi; ++i) { i != eoi; ++i) {
char host[NI_MAXHOST]; char host[NI_MAXHOST];
int s; int s;
s = getnameinfo(reinterpret_cast<const struct sockaddr*>(&(*i).first), s = getnameinfo(&(*i).first.sa, (*i).second, host, NI_MAXHOST, 0, 0,
(*i).second,
host, NI_MAXHOST, 0, 0,
NI_NUMERICHOST); NI_NUMERICHOST);
if(s) { if(s) {
error = gai_strerror(s); error = gai_strerror(s);
@ -336,11 +334,10 @@ void SocketCore::beginListen()
SocketCore* SocketCore::acceptConnection() const SocketCore* SocketCore::acceptConnection() const
{ {
struct sockaddr_storage sockaddr; sockaddr_union sockaddr;
socklen_t len = sizeof(sockaddr); socklen_t len = sizeof(sockaddr);
sock_t fd; sock_t fd;
while((fd = accept(sockfd_, reinterpret_cast<struct sockaddr*>(&sockaddr), while((fd = accept(sockfd_, &sockaddr.sa, &len)) == (sock_t) -1 &&
&len)) == (sock_t) -1 &&
SOCKET_ERRNO == A2_EINTR); SOCKET_ERRNO == A2_EINTR);
int errNum = SOCKET_ERRNO; int errNum = SOCKET_ERRNO;
if(fd == (sock_t) -1) { if(fd == (sock_t) -1) {
@ -351,18 +348,15 @@ SocketCore* SocketCore::acceptConnection() const
void SocketCore::getAddrInfo(std::pair<std::string, uint16_t>& addrinfo) const void SocketCore::getAddrInfo(std::pair<std::string, uint16_t>& addrinfo) const
{ {
struct sockaddr_storage sockaddr; sockaddr_union sockaddr;
socklen_t len = sizeof(sockaddr); socklen_t len = sizeof(sockaddr);
getAddrInfo(sockaddr, len); getAddrInfo(sockaddr, len);
addrinfo = util::getNumericNameInfo addrinfo = util::getNumericNameInfo(&sockaddr.sa, len);
(reinterpret_cast<const struct sockaddr*>(&sockaddr), len);
} }
void SocketCore::getAddrInfo void SocketCore::getAddrInfo(sockaddr_union& sockaddr, socklen_t& len) const
(struct sockaddr_storage& sockaddr, socklen_t& len) const
{ {
struct sockaddr* addrp = reinterpret_cast<struct sockaddr*>(&sockaddr); if(getsockname(sockfd_, &sockaddr.sa, &len) == -1) {
if(getsockname(sockfd_, addrp, &len) == -1) {
int errNum = SOCKET_ERRNO; int errNum = SOCKET_ERRNO;
throw DL_ABORT_EX(fmt(EX_SOCKET_GET_NAME, errorMsg(errNum).c_str())); throw DL_ABORT_EX(fmt(EX_SOCKET_GET_NAME, errorMsg(errNum).c_str()));
} }
@ -370,22 +364,21 @@ void SocketCore::getAddrInfo
int SocketCore::getAddressFamily() const int SocketCore::getAddressFamily() const
{ {
struct sockaddr_storage sockaddr; sockaddr_union sockaddr;
socklen_t len = sizeof(sockaddr); socklen_t len = sizeof(sockaddr);
getAddrInfo(sockaddr, len); getAddrInfo(sockaddr, len);
return sockaddr.ss_family; return sockaddr.storage.ss_family;
} }
void SocketCore::getPeerInfo(std::pair<std::string, uint16_t>& peerinfo) const void SocketCore::getPeerInfo(std::pair<std::string, uint16_t>& peerinfo) const
{ {
struct sockaddr_storage sockaddr; sockaddr_union sockaddr;
socklen_t len = sizeof(sockaddr); socklen_t len = sizeof(sockaddr);
struct sockaddr* addrp = reinterpret_cast<struct sockaddr*>(&sockaddr); if(getpeername(sockfd_, &sockaddr.sa, &len) == -1) {
if(getpeername(sockfd_, addrp, &len) == -1) {
int errNum = SOCKET_ERRNO; int errNum = SOCKET_ERRNO;
throw DL_ABORT_EX(fmt(EX_SOCKET_GET_NAME, errorMsg(errNum).c_str())); throw DL_ABORT_EX(fmt(EX_SOCKET_GET_NAME, errorMsg(errNum).c_str()));
} }
peerinfo = util::getNumericNameInfo(addrp, len); peerinfo = util::getNumericNameInfo(&sockaddr.sa, len);
} }
void SocketCore::establishConnection(const std::string& host, uint16_t port) void SocketCore::establishConnection(const std::string& host, uint16_t port)
@ -421,11 +414,10 @@ void SocketCore::establishConnection(const std::string& host, uint16_t port)
} }
if(!bindAddrs_.empty()) { if(!bindAddrs_.empty()) {
bool bindSuccess = false; bool bindSuccess = false;
for(std::vector<std::pair<struct sockaddr_storage, socklen_t> >:: for(std::vector<std::pair<sockaddr_union, socklen_t> >::
const_iterator i = bindAddrs_.begin(), eoi = bindAddrs_.end(); const_iterator i = bindAddrs_.begin(), eoi = bindAddrs_.end();
i != eoi; ++i) { i != eoi; ++i) {
if(::bind(fd,reinterpret_cast<const struct sockaddr*>(&(*i).first), if(::bind(fd, &(*i).first.sa, (*i).second) == -1) {
(*i).second) == -1) {
errNum = SOCKET_ERRNO; errNum = SOCKET_ERRNO;
error = errorMsg(errNum); error = errorMsg(errNum);
A2_LOG_DEBUG(fmt(EX_SOCKET_BIND, error.c_str())); A2_LOG_DEBUG(fmt(EX_SOCKET_BIND, error.c_str()));
@ -1056,12 +1048,11 @@ ssize_t SocketCore::readDataFrom(char* data, size_t len,
{ {
wantRead_ = false; wantRead_ = false;
wantWrite_ = false; wantWrite_ = false;
struct sockaddr_storage sockaddr; sockaddr_union sockaddr;
socklen_t sockaddrlen = sizeof(struct sockaddr_storage); socklen_t sockaddrlen = sizeof(sockaddr);
struct sockaddr* addrp = reinterpret_cast<struct sockaddr*>(&sockaddr);
ssize_t r; ssize_t r;
while((r = recvfrom(sockfd_, data, len, 0, addrp, &sockaddrlen)) == -1 && while((r = recvfrom(sockfd_, data, len, 0, &sockaddr.sa, &sockaddrlen)) == -1
A2_EINTR == SOCKET_ERRNO); && A2_EINTR == SOCKET_ERRNO);
int errNum = SOCKET_ERRNO; int errNum = SOCKET_ERRNO;
if(r == -1) { if(r == -1) {
if(A2_WOULDBLOCK(errNum)) { if(A2_WOULDBLOCK(errNum)) {
@ -1071,7 +1062,7 @@ ssize_t SocketCore::readDataFrom(char* data, size_t len,
throw DL_RETRY_EX(fmt(EX_SOCKET_RECV, errorMsg(errNum).c_str())); throw DL_RETRY_EX(fmt(EX_SOCKET_RECV, errorMsg(errNum).c_str()));
} }
} else { } else {
sender = util::getNumericNameInfo(addrp, sockaddrlen); sender = util::getNumericNameInfo(&sockaddr.sa, sockaddrlen);
} }
return r; return r;
@ -1108,23 +1099,19 @@ bool SocketCore::wantWrite() const
void SocketCore::bindAddress(const std::string& iface) void SocketCore::bindAddress(const std::string& iface)
{ {
std::vector<std::pair<struct sockaddr_storage, socklen_t> > bindAddrs; std::vector<std::pair<sockaddr_union, socklen_t> > bindAddrs;
getInterfaceAddress(bindAddrs, iface, protocolFamily_); getInterfaceAddress(bindAddrs, iface, protocolFamily_);
if(bindAddrs.empty()) { if(bindAddrs.empty()) {
throw DL_ABORT_EX throw DL_ABORT_EX
(fmt(MSG_INTERFACE_NOT_FOUND, (fmt(MSG_INTERFACE_NOT_FOUND, iface.c_str(), "not available"));
iface.c_str(),
"not available"));
} else { } else {
bindAddrs_ = bindAddrs; bindAddrs_.swap(bindAddrs);
for(std::vector<std::pair<struct sockaddr_storage, socklen_t> >:: for(std::vector<std::pair<sockaddr_union, socklen_t> >::
const_iterator i = bindAddrs_.begin(), eoi = bindAddrs_.end(); const_iterator i = bindAddrs_.begin(), eoi = bindAddrs_.end();
i != eoi; ++i) { i != eoi; ++i) {
char host[NI_MAXHOST]; char host[NI_MAXHOST];
int s; int s;
s = getnameinfo(reinterpret_cast<const struct sockaddr*>(&(*i).first), s = getnameinfo(&(*i).first.sa, (*i).second, host, NI_MAXHOST, 0, 0,
(*i).second,
host, NI_MAXHOST, 0, 0,
NI_NUMERICHOST); NI_NUMERICHOST);
if(s == 0) { if(s == 0) {
A2_LOG_DEBUG(fmt("Sockets will bind to %s", host)); A2_LOG_DEBUG(fmt("Sockets will bind to %s", host));
@ -1134,7 +1121,7 @@ void SocketCore::bindAddress(const std::string& iface)
} }
void getInterfaceAddress void getInterfaceAddress
(std::vector<std::pair<struct sockaddr_storage, socklen_t> >& ifAddrs, (std::vector<std::pair<sockaddr_union, socklen_t> >& ifAddrs,
const std::string& iface, int family, int aiFlags) const std::string& iface, int family, int aiFlags)
{ {
A2_LOG_DEBUG(fmt("Finding interface %s", iface.c_str())); A2_LOG_DEBUG(fmt("Finding interface %s", iface.c_str()));
@ -1146,8 +1133,8 @@ void getInterfaceAddress
A2_LOG_INFO(fmt(MSG_INTERFACE_NOT_FOUND, A2_LOG_INFO(fmt(MSG_INTERFACE_NOT_FOUND,
iface.c_str(), errorMsg(errNum).c_str())); iface.c_str(), errorMsg(errNum).c_str()));
} else { } else {
auto_delete<struct ifaddrs*> ifaddrDeleter(ifaddr, freeifaddrs); auto_delete<ifaddrs*> ifaddrDeleter(ifaddr, freeifaddrs);
for(struct ifaddrs* ifa = ifaddr; ifa; ifa = ifa->ifa_next) { for(ifaddrs* ifa = ifaddr; ifa; ifa = ifa->ifa_next) {
if(!ifa->ifa_addr) { if(!ifa->ifa_addr) {
continue; continue;
} }
@ -1168,37 +1155,36 @@ void getInterfaceAddress
continue; continue;
} }
if(std::string(ifa->ifa_name) == iface) { if(std::string(ifa->ifa_name) == iface) {
socklen_t bindAddrLen = iffamily == AF_INET?sizeof(struct sockaddr_in): socklen_t bindAddrLen =
sizeof(struct sockaddr_in6); iffamily == AF_INET ? sizeof(sockaddr_in) : sizeof(sockaddr_in6);
struct sockaddr_storage bindAddr; sockaddr_union bindAddr;
memset(&bindAddr, 0, sizeof(bindAddr)); memset(&bindAddr, 0, sizeof(bindAddr));
memcpy(&bindAddr, ifa->ifa_addr, bindAddrLen); memcpy(&bindAddr.storage, ifa->ifa_addr, bindAddrLen);
ifAddrs.push_back(std::make_pair(bindAddr, bindAddrLen)); ifAddrs.push_back(std::make_pair(bindAddr, bindAddrLen));
} }
} }
} }
#endif // HAVE_GETIFADDRS #endif // HAVE_GETIFADDRS
if(ifAddrs.empty()) { if(ifAddrs.empty()) {
struct addrinfo* res; addrinfo* res;
int s; int s;
s = callGetaddrinfo(&res, iface.c_str(), 0, family, SOCK_STREAM, aiFlags,0); s = callGetaddrinfo(&res, iface.c_str(), 0, family, SOCK_STREAM, aiFlags,0);
if(s) { if(s) {
A2_LOG_INFO(fmt(MSG_INTERFACE_NOT_FOUND, iface.c_str(), gai_strerror(s))); A2_LOG_INFO(fmt(MSG_INTERFACE_NOT_FOUND, iface.c_str(), gai_strerror(s)));
} else { } else {
WSAAPI_AUTO_DELETE<struct addrinfo*> resDeleter(res, freeaddrinfo); WSAAPI_AUTO_DELETE<addrinfo*> resDeleter(res, freeaddrinfo);
struct addrinfo* rp; addrinfo* rp;
for(rp = res; rp; rp = rp->ai_next) { for(rp = res; rp; rp = rp->ai_next) {
socklen_t bindAddrLen = rp->ai_addrlen;
struct sockaddr_storage bindAddr;
memset(&bindAddr, 0, sizeof(bindAddr));
memcpy(&bindAddr, rp->ai_addr, rp->ai_addrlen);
// Try to bind socket with this address. If it fails, the // Try to bind socket with this address. If it fails, the
// address is not for this machine. // address is not for this machine.
try { try {
SocketCore socket; SocketCore socket;
socket.bind //socket.bind(&bindAddr.sa, bindAddrLen);
(reinterpret_cast<const struct sockaddr*>(&bindAddr), bindAddrLen); socket.bind(rp->ai_addr, rp->ai_addrlen);
ifAddrs.push_back(std::make_pair(bindAddr, bindAddrLen)); sockaddr_union bindAddr;
memset(&bindAddr, 0, sizeof(bindAddr));
memcpy(&bindAddr.storage, rp->ai_addr, rp->ai_addrlen);
ifAddrs.push_back(std::make_pair(bindAddr, rp->ai_addrlen));
} catch(RecoverableException& e) { } catch(RecoverableException& e) {
continue; continue;
} }

View File

@ -76,7 +76,7 @@ private:
static int protocolFamily_; static int protocolFamily_;
static std::vector<std::pair<struct sockaddr_storage, socklen_t> > bindAddrs_; static std::vector<std::pair<sockaddr_union, socklen_t> > bindAddrs_;
bool blocking_; bool blocking_;
int secure_; int secure_;
@ -159,7 +159,7 @@ public:
* in len. * in len.
*/ */
void getAddrInfo void getAddrInfo
(struct sockaddr_storage& sockaddr, socklen_t& len) const; (sockaddr_union& sockaddr, socklen_t& len) const;
/** /**
* Returns address family of this socket. * Returns address family of this socket.
@ -344,7 +344,7 @@ public:
static void bindAddress(const std::string& iface); static void bindAddress(const std::string& iface);
friend void getInterfaceAddress friend void getInterfaceAddress
(std::vector<std::pair<struct sockaddr_storage, socklen_t> >& ifAddrs, (std::vector<std::pair<sockaddr_union, socklen_t> >& ifAddrs,
const std::string& iface, int family, int aiFlags); const std::string& iface, int family, int aiFlags);
}; };
@ -366,7 +366,7 @@ int callGetaddrinfo
// to collect using family argument. aiFlags is passed to // to collect using family argument. aiFlags is passed to
// getaddrinfo() as hints.ai_flags. No throw. // getaddrinfo() as hints.ai_flags. No throw.
void getInterfaceAddress void getInterfaceAddress
(std::vector<std::pair<struct sockaddr_storage, socklen_t> >& ifAddrs, (std::vector<std::pair<sockaddr_union, socklen_t> >& ifAddrs,
const std::string& iface, int family = AF_UNSPEC, int aiFlags = 0); const std::string& iface, int family = AF_UNSPEC, int aiFlags = 0);
// Provides functionality of inet_ntop using getnameinfo. The return // Provides functionality of inet_ntop using getnameinfo. The return