SocketUnixAddress get_unix_address(const SocketInetAddress& addr) { return get_unix_address(addr.GetRawSockAddr()); }
SocketHostAddress get_host_address(const SocketInetAddress& addr) { return get_host_address(addr.GetRawSockAddr()); }
bool ServerSocketChannel::DoBind(Address* local) { if (m_fd > 0) { return true; } int on = 1; SocketInetAddress addr; if (InstanceOf<SocketHostAddress>(local).OK) { SocketHostAddress* host_addr = (SocketHostAddress*) local; addr = get_inet_address(host_addr->GetHost(), host_addr->GetPort()); } else if (InstanceOf<SocketInetAddress>(local).OK) { SocketInetAddress* inet_addr = (SocketInetAddress*) local; addr = (*inet_addr); } else if (InstanceOf<SocketUnixAddress>(local).OK) { SocketUnixAddress* unix_addr = (SocketUnixAddress*) local; int ret = unlink(unix_addr->GetPath().c_str()); // in case it already exists if (ret == -1) { int e = errno; ERROR_LOG( "unlink %s failed:%s", unix_addr->GetPath().c_str(), strerror(e)); } addr = get_inet_address(*unix_addr); } else { return false; } int family = addr.GetRawSockAddr().sa_family; int fd = ::socket(family, SOCK_STREAM, 0); if (fd < 0) { return false; } if (make_fd_nonblocking(fd) < 0) { ::close(fd); return false; } if (!addr.IsUnix()) { if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) { ::close(fd); return false; } } else { struct sockaddr_un* pun = (struct sockaddr_un*) &(addr.GetRawSockAddr()); DEBUG_LOG("Bind on %s", pun->sun_path); // int nZero = 0; // setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (char *) &nZero, sizeof(nZero)); // setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (char *) &nZero, sizeof(int)); } //setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (void*) &on, sizeof(on)); if (::bind(fd, (struct sockaddr*) &(addr.GetRawSockAddr()), addr.GetRawSockAddrSize()) == -1) { int e = errno; ERROR_LOG("Failed to bind address for reason:%s", strerror(e)); ::close(fd); return false; } if (::listen(fd, 511) == -1) { /* the magic 511 constant is from nginx */ int e = errno; ERROR_LOG("Failed to listen for reason:%s", strerror(e)); ::close(fd); return false; } if (aeCreateFileEvent(GetService().GetRawEventLoop(), fd, AE_READABLE, Channel::IOEventCallback, this) == AE_ERR) { ::close(fd); return false; } m_fd = fd; return true; }