Ejemplo n.º 1
0
void irc_destroy_session (irc_session_t * session)
{
	free_ircsession_strings( session );

	// The CTCP VERSION must be freed only now
	if ( session->ctcp_version )
		free (session->ctcp_version);

	if ( session->sock >= 0 )
		socket_close (&session->sock);

#if defined (ENABLE_THREADS)
	libirc_mutex_destroy (&session->mutex_session);
#endif

#if defined (ENABLE_SSL)
	if ( session->ssl )
		SSL_free( session->ssl );
#endif

	/*
	 * delete DCC data
	 * libirc_remove_dcc_session removes the DCC session from the list.
	 */
	while ( session->dcc_sessions )
		libirc_remove_dcc_session (session, session->dcc_sessions, 0);

	libirc_mutex_destroy (&session->mutex_dcc);

	free (session);
}
Ejemplo n.º 2
0
void irc_destroy_session(irc_session_t * session) {
    free_ircsession_strings(session);

    if (session->sock >= 0)
        socket_close(&session->sock);

#if defined (ENABLE_THREADS)
    libirc_mutex_destroy(&session->mutex_session);
#endif

    while (session->dcc_sessions)
        libirc_remove_dcc_session(session, session->dcc_sessions, 0);

    free_line_parser(session->line_parser);
    fdwatch_free();

#ifdef ENABLE_SSL
    if (session->ssl)
        SSL_free(session->ssl);
#endif

    free(session);
}
Ejemplo n.º 3
0
int irc_connect_generic(irc_session_t * session,
                        const char * server,
                        unsigned short port,
                        const char * server_password,
                        const char * nick,
                        const char * username,
                        const char * realname,
                        int protocol_family) {
    struct irc_addr_t **addresses;
    int numAddresses = 0;

    if (!server || !nick) {
        session->lasterror = LIBIRC_ERR_INVAL;
        return 1;
    }

    if (session->state != LIBIRC_STATE_INIT) {
        session->lasterror = LIBIRC_ERR_STATE;
        return 1;
    }

    // Free the strings if defined; may be the case when the session is reused after the connection fails
    free_ircsession_strings(session);

    if (server[0] == SSL_PREFIX) {
#if defined (ENABLE_SSL)
        server++;
        session->flags |= SESSIONFL_SSL_CONNECTION;
#else
        session->lasterror = LIBIRC_ERR_SSL_NOT_SUPPORTED;
        return 1;
#endif
    }

    if (username)
        session->username = strdup(username);

    if (server_password)
        session->server_password = strdup(server_password);

    if (realname)
        session->realname = strdup(realname);

    session->nick = strdup(nick);
    session->server = strdup(server);

    addresses = resolve_hostname_by_dns(session->server, &numAddresses, protocol_family);

    if (addresses == NULL) {
        session->lasterror = LIBIRC_ERR_RESOLV;
        return 1;
    }

    int selectedAddress = rand_range(0, numAddresses - 1);

    // and connect to the IRC server
    for (; addresses[selectedAddress] != NULL; selectedAddress++) {
        struct irc_addr_t *currentAddress = addresses[selectedAddress];
        int ret = -1;

        if (currentAddress->family == AF_INET)
            ret = try_to_connect_ipv4(session, currentAddress, port);
#if defined (ENABLE_IPV6)
        else if (currentAddress->family == AF_INET6)
            ret = try_to_connect_ipv6(session, currentAddress, port);
#endif

        if (ret == -1) {
            goto err_out;
        }

        if (hasConnection(session)) {
            break;
        } else {
            socket_close(&session->sock);
        }
    }

    if (addresses[selectedAddress] == NULL) {
        session->lasterror = LIBIRC_ERR_CONNECT;
        goto err_out;
    }

    logprintf(LOG_INFO, "Connection successful!");

    free_addresses(addresses);

    session->state = LIBIRC_STATE_CONNECTING;
    if (protocol_family == AF_INET6)
        session->flags |= SESSIONFL_USES_IPV6;

    return 0;

err_out:
    free_addresses(addresses);
    return 1;
}
Ejemplo n.º 4
0
int irc_connect6 (irc_session_t * session,
			const char * server,
			unsigned short port,
			const char * server_password,
			const char * nick,
			const char * username,
			const char * realname)
{
#if defined (ENABLE_IPV6)
	struct sockaddr_in6 saddr;
	struct addrinfo ainfo, *res = NULL;
	char portStr[32], *p;
#if defined (_WIN32)
	int addrlen = sizeof(saddr);
	HMODULE hWsock;
	getaddrinfo_ptr_t getaddrinfo_ptr;
	freeaddrinfo_ptr_t freeaddrinfo_ptr;
	int resolvesuccess = 0;
#endif

	// Check and copy all the specified fields
	if ( !server || !nick )
	{
		session->lasterror = LIBIRC_ERR_INVAL;
		return 1;
	}

	if ( session->state != LIBIRC_STATE_INIT )
	{
		session->lasterror = LIBIRC_ERR_STATE;
		return 1;
	}

	// Free the strings if defined; may be the case when the session is reused after the connection fails
	free_ircsession_strings( session );

	// Handle the server # prefix (SSL)
	if ( server[0] == SSL_PREFIX )
	{
#if defined (ENABLE_SSL)
		server++;
		session->flags |= SESSIONFL_SSL_CONNECTION;
#else
		session->lasterror = LIBIRC_ERR_SSL_NOT_SUPPORTED;
		return 1;
#endif
	}

	if ( username )
		session->username = strdup (username);

	if ( server_password )
		session->server_password = strdup (server_password);

	if ( realname )
		session->realname = strdup (realname);

	session->nick = strdup (nick);
	session->server = strdup (server);

	// If port number is zero and server contains the port, parse it
	if ( port == 0 && (p = strchr( session->server, ':' )) != 0 )
	{
		// Terminate the string and parse the port number
		*p++ = '\0';
		port = atoi( p );
	}

	memset( &saddr, 0, sizeof(saddr) );
	saddr.sin6_family = AF_INET6;
	saddr.sin6_port = htons (port);

	sprintf( portStr, "%u", (unsigned)port );

#if defined (_WIN32)
	if ( WSAStringToAddressA( (LPSTR)session->server, AF_INET6, NULL, (struct sockaddr *)&saddr, &addrlen ) == SOCKET_ERROR )
	{
		hWsock = LoadLibraryA("ws2_32");

		if (hWsock)
		{
			/* Determine functions at runtime, because windows systems < XP do not
			 * support getaddrinfo. */
			getaddrinfo_ptr = (getaddrinfo_ptr_t)GetProcAddress(hWsock, "getaddrinfo");
			freeaddrinfo_ptr = (freeaddrinfo_ptr_t)GetProcAddress(hWsock, "freeaddrinfo");

			if (getaddrinfo_ptr && freeaddrinfo_ptr)
			{
				memset(&ainfo, 0, sizeof(ainfo));
				ainfo.ai_family = AF_INET6;
				ainfo.ai_socktype = SOCK_STREAM;
				ainfo.ai_protocol = 0;

				if ( getaddrinfo_ptr(session->server, portStr, &ainfo, &res) == 0 && res )
				{
					resolvesuccess = 1;
					memcpy( &saddr, res->ai_addr, res->ai_addrlen );
					freeaddrinfo_ptr( res );
				}
			}
			FreeLibrary(hWsock);
		}
		if (!resolvesuccess)
		{
			session->lasterror = LIBIRC_ERR_RESOLV;
			return 1;
		}
	}
#else
	if ( inet_pton( AF_INET6, session->server, (void*) &saddr.sin6_addr ) <= 0 )
	{
		memset( &ainfo, 0, sizeof(ainfo) );
		ainfo.ai_family = AF_INET6;
		ainfo.ai_socktype = SOCK_STREAM;
		ainfo.ai_protocol = 0;

		if ( getaddrinfo( session->server, portStr, &ainfo, &res ) || !res )
		{
			session->lasterror = LIBIRC_ERR_RESOLV;
			return 1;
		}

		memcpy( &saddr, res->ai_addr, res->ai_addrlen );
		freeaddrinfo( res );
	}
#endif

	// create the IRC server socket
	if ( socket_create( PF_INET6, SOCK_STREAM, &session->sock)
	|| socket_make_nonblocking (&session->sock) )
	{
		session->lasterror = LIBIRC_ERR_SOCKET;
		return 1;
	}

#if defined (ENABLE_SSL)
	// Init the SSL stuff
	if ( session->flags & SESSIONFL_SSL_CONNECTION )
	{
		int rc = ssl_init( session );

		if ( rc != 0 )
			return rc;
	}
#endif

    // and connect to the IRC server
    if ( socket_connect (&session->sock, (struct sockaddr *) &saddr, sizeof(saddr)) )
    {
    	session->lasterror = LIBIRC_ERR_CONNECT;
		return 1;
    }

    session->state = LIBIRC_STATE_CONNECTING;
    session->flags = 0; // reset in case of reconnect
	return 0;
#else
	session->lasterror = LIBIRC_ERR_NOIPV6;
	return 1;
#endif
}
Ejemplo n.º 5
0
int irc_connect (irc_session_t * session,
			const char * server,
			unsigned short port,
			const char * server_password,
			const char * nick,
			const char * username,
			const char * realname)
{
	struct sockaddr_in saddr;
	char * p;

	// Check and copy all the specified fields
	if ( !server || !nick )
	{
		session->lasterror = LIBIRC_ERR_INVAL;
		return 1;
	}

	if ( session->state != LIBIRC_STATE_INIT )
	{
		session->lasterror = LIBIRC_ERR_STATE;
		return 1;
	}

	// Free the strings if defined; may be the case when the session is reused after the connection fails
	free_ircsession_strings( session );

	// Handle the server # prefix (SSL)
	if ( server[0] == SSL_PREFIX )
	{
#if defined (ENABLE_SSL)
		server++;
		session->flags |= SESSIONFL_SSL_CONNECTION;
#else
		session->lasterror = LIBIRC_ERR_SSL_NOT_SUPPORTED;
		return 1;
#endif
	}

	if ( username )
		session->username = strdup (username);

	if ( server_password )
		session->server_password = strdup (server_password);

	if ( realname )
		session->realname = strdup (realname);

	session->nick = strdup (nick);
	session->server = strdup (server);

	// If port number is zero and server contains the port, parse it
	if ( port == 0 && (p = strchr( session->server, ':' )) != 0 )
	{
		// Terminate the string and parse the port number
		*p++ = '\0';
		port = atoi( p );
	}

	// IPv4 address resolving
	memset( &saddr, 0, sizeof(saddr) );
	saddr.sin_family = AF_INET;
	saddr.sin_port = htons (port);
	saddr.sin_addr.s_addr = inet_addr( session->server );

    if ( saddr.sin_addr.s_addr == INADDR_NONE )
    {
		struct hostent *hp;
#if defined HAVE_GETHOSTBYNAME_R
		int tmp_errno;
		struct hostent tmp_hostent;
		char buf[2048];

      	if ( gethostbyname_r (session->server, &tmp_hostent, buf, sizeof(buf), &hp, &tmp_errno) )
      		hp = 0;
#else
      	hp = gethostbyname (session->server);
#endif // HAVE_GETHOSTBYNAME_R
		if ( !hp )
		{
			session->lasterror = LIBIRC_ERR_RESOLV;
			return 1;
		}

		memcpy (&saddr.sin_addr, hp->h_addr, (size_t) hp->h_length);
    }

    // create the IRC server socket
	if ( socket_create( PF_INET, SOCK_STREAM, &session->sock)
	|| socket_make_nonblocking (&session->sock) )
	{
		session->lasterror = LIBIRC_ERR_SOCKET;
		return 1;
	}

#if defined (ENABLE_SSL)
	// Init the SSL stuff
	if ( session->flags & SESSIONFL_SSL_CONNECTION )
	{
		int rc = ssl_init( session );

		if ( rc != 0 )
		{
			session->lasterror = rc;
			return 1;
		}
	}
#endif

    // and connect to the IRC server
    if ( socket_connect (&session->sock, (struct sockaddr *) &saddr, sizeof(saddr)) )
    {
    	session->lasterror = LIBIRC_ERR_CONNECT;
		return 1;
    }

    session->state = LIBIRC_STATE_CONNECTING;
    session->flags = SESSIONFL_USES_IPV6; // reset in case of reconnect
	return 0;
}