KSocketAddress KSocketDevice::peerAddress() const { if (m_sockfd == -1) return KSocketAddress(); // not open, empty value if (d->peer.family() != AF_UNSPEC) return d->peer; socklen_t len; KSocketAddress peerAddress; peerAddress.setLength(len = 32); // arbitrary value if (kde_getpeername(m_sockfd, peerAddress.address(), &len) == -1) // error! return d->peer = KSocketAddress(); #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN len = peerAddress.address()->sa_len; #endif if (len <= peerAddress.length()) { // it has fit already peerAddress.setLength(len); return d->peer = peerAddress; } // no, the socket address is actually larger than we had anticipated // call again peerAddress.setLength(len); if (kde_getpeername(m_sockfd, peerAddress.address(), &len) == -1) // error! return d->peer = KSocketAddress(); return d->peer = peerAddress; }
bool KInetSocketAddress::areEqualInet(const KSocketAddress &s1, const KSocketAddress &s2, bool coreOnly) { if(s1.family() != s2.family()) return false; if((s1.size() < sizeof(sockaddr_in)) || (s2.size() < sizeof(sockaddr_in))) return false; struct sockaddr_in *sin1 = (sockaddr_in *)s1.address(); struct sockaddr_in *sin2 = (sockaddr_in *)s2.address(); if(coreOnly) return (memcmp(&sin1->sin_addr, &sin2->sin_addr, sizeof(struct in_addr)) == 0); else return (sin1->sin_port == sin2->sin_port) && (memcmp(&sin1->sin_addr, &sin2->sin_addr, sizeof(struct in_addr)) == 0); }
bool KSocketDevice::disconnect() { resetError(); if (m_sockfd == -1) return false; // can't create KSocketAddress address; address.setFamily(AF_UNSPEC); if (kde_connect(m_sockfd, address.address(), address.length()) == -1) { if (errno == EALREADY || errno == EINPROGRESS) { setError(IO_ConnectError, InProgress); return false; } else if (errno == ECONNREFUSED) setError(IO_ConnectError, ConnectionRefused); else if (errno == ENETDOWN || errno == ENETUNREACH || errno == ENETRESET || errno == ECONNABORTED || errno == ECONNRESET || errno == EHOSTDOWN || errno == EHOSTUNREACH) setError(IO_ConnectError, NetFailure); else setError(IO_ConnectError, NotSupported); return false; } setFlags(IO_Sequential | IO_Raw | IO_ReadWrite); setState(IO_Open); return true; // all is well }
void PortListener::accepted(KSocket *sock) { QString host, port; KSocketAddress *ksa = KExtendedSocket::peerAddress(sock->socket()); if ((!ksa) || !ksa->address()) { delete sock; return; } KExtendedSocket::resolve(ksa, host, port); KNotifyClient::event("IncomingConnection", i18n("Connection from %1").arg(host)); delete ksa; if ((!m_enabled) || ((!m_multiInstance) && m_process.isRunning())) { delete sock; return; } // disable CLOEXEC flag, fixes #77412 fcntl(sock->socket(), F_SETFD, fcntl(sock->socket(), F_GETFD) & ~FD_CLOEXEC); m_process.clearArguments(); m_process << m_execPath << m_argument << QString::number(sock->socket()); if (!m_process.start(KProcess::DontCare)) { KNotifyClient::event("ProcessFailed", i18n("Call \"%1 %2 %3\" failed").arg(m_execPath) .arg(m_argument) .arg(sock->socket())); } delete sock; }
bool KUnixSocketAddress::areEqualUnix(const KSocketAddress &s1, const KSocketAddress &s2, bool /* coreOnly */) { if(s1.family() != s2.family()) return false; if((s1.size() < MIN_SOCKADDR_LEN) || (s2.size() < MIN_SOCKADDR_LEN)) return false; struct sockaddr_un *sun1 = (sockaddr_un *)s1.address(); struct sockaddr_un *sun2 = (sockaddr_un *)s2.address(); if(s1.size() == MIN_SOCKADDR_LEN && s2.size() == MIN_SOCKADDR_LEN) return true; // unnamed Unix sockets return (strcmp(sun1->sun_path, sun2->sun_path) == 0); }
bool KInetSocketAddress::areEqualInet6(const KSocketAddress &s1, const KSocketAddress &s2, bool coreOnly) { #ifdef AF_INET6 if(s1.family() != s2.family()) return false; if((s1.size() < sizeof(sockaddr_in6)) || (s2.size() < sizeof(sockaddr_in6))) return false; struct sockaddr_in6 *sin1 = (sockaddr_in6 *)s1.address(); struct sockaddr_in6 *sin2 = (sockaddr_in6 *)s2.address(); if(coreOnly) return (memcmp(&sin1->sin6_addr, &sin2->sin6_addr, sizeof(struct in6_addr)) == 0); else return (sin1->sin6_port == sin2->sin6_port) && (sin1->sin6_flowinfo == sin2->sin6_flowinfo) && #ifdef HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID (sin1->sin6_scope_id == sin2->sin6_scope_id) && #endif (memcmp(&sin1->sin6_addr, &sin2->sin6_addr, sizeof(struct in6_addr)) == 0); #else return false; #endif }
Q_LONG KSocketDevice::writeBlock(const char *data, Q_ULONG len, const KSocketAddress& to) { resetError(); if (m_sockfd == -1) return -1; // can't write to unopen socket if (data == 0L || len == 0) return 0; // nothing to be written ssize_t retval = ::sendto(m_sockfd, data, len, 0, to.address(), to.length()); if (retval == -1) { if (errno == EAGAIN || errno == EWOULDBLOCK) setError(IO_WriteError, WouldBlock); else setError(IO_WriteError, UnknownError); return -1; // nothing written } else if (retval == 0) setError(IO_WriteError, RemotelyDisconnected); return retval; }