예제 #1
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
}
예제 #2
0
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;
}
예제 #3
0
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;
}
예제 #4
0
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;
}
예제 #5
0
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);
}
예제 #6
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);
}
예제 #7
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
}
예제 #8
0
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
}