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; }
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; }
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; }
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::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 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 }
bool testKernel() { #ifndef AF_INET6 printf("\tAF_INET6 unknown. Can't test anything\n"); return false; #else int sock; kde_sockaddr_in6 sin6; socklen_t len = sizeof(sin6); printf("\tAF_INET6 == %d\n", AF_INET6); printf("\tTrying to create an IPv6 socket..."); sock = socket(AF_INET6, SOCK_STREAM, 0); if(sock == -1) printf("failed\n\tReason was: %s", strerror(errno)); else { printf("succeeded\n"); if(getsockname(sock, (struct sockaddr *)&sin6, &len) == 0) printf("\tSize of kernel's sockaddr_in6 is %d bytes\n", len); else printf("\tCould not get socket name\n"); } printf("\tSize of KDE's internal sockaddr_in6 is %d bytes\n", sizeof(kde_sockaddr_in6)); #ifdef HAVE_SOCKADDR_IN6 printf("\tSize of system libraries' sockaddr_in6 is %d bytes\n", sizeof(sockaddr_in6)); #else printf("\tSystem libraries don't define sockaddr_in6\n"); #endif if(sock == -1) return false; printf("\tTrying to bind the socket to an address..."); sin6.sin6_family = AF_INET6; #ifdef HAVE_SOCKADDR_SA_LEN sin6.sin6_len = sizeof(sin6); #endif sin6.sin6_flowinfo = 0; sin6.sin6_scope_id = 0; sin6.sin6_port = 0; // bind to any port memset(&sin6.sin6_addr, 0, sizeof(sin6.sin6_addr)); // any address if(bind(sock, (sockaddr *)&sin6, sizeof(sin6)) == -1) { printf("failed\n\tReason was: %s\n", strerror(errno)); close(sock); return false; } printf("succeeded\n"); KSocketAddress *ksin = KExtendedSocket::localAddress(sock); if(ksin != NULL) { printf("\tWe got socket %s\n", (const char *)ksin->pretty().latin1()); delete ksin; } close(sock); return true; #endif // AF_INET6 }