Esempio n. 1
0
int init_socket(irc_session_t *session, int addressFamily) {// create the IRC server socket
    if (socket_create(addressFamily, 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

    return 0;
}
Esempio n. 2
0
static int libirc_new_dcc_session (irc_session_t * session, unsigned long ip, unsigned short port, int dccmode, void * ctx, irc_dcc_session_t ** pdcc)
{
	irc_dcc_session_t * dcc = malloc (sizeof(irc_dcc_session_t));

	if ( !dcc )
		return LIBIRC_ERR_NOMEM;

	// setup
	memset (dcc, 0, sizeof(irc_dcc_session_t));

	dcc->dccsend_file_fp = 0;

	if ( libirc_mutex_init (&dcc->mutex_outbuf) )
		goto cleanup_exit_error;

	if ( socket_create (PF_INET, SOCK_STREAM, &dcc->sock) )
		goto cleanup_exit_error;

	if ( !ip )
	{
		struct sockaddr_in saddr;
		unsigned long arg = 1;

		setsockopt (dcc->sock, SOL_SOCKET, SO_REUSEADDR, (char*)&arg, sizeof(arg));

		memset (&saddr, 0, sizeof(saddr));
		saddr.sin_family = AF_INET;
		memcpy (&saddr.sin_addr, &session->local_addr, sizeof(session->local_addr));
        saddr.sin_port = htons (0);

		if ( bind (dcc->sock, (struct sockaddr *) &saddr, sizeof(saddr)) < 0 )
			goto cleanup_exit_error;

		if ( listen (dcc->sock, 5) < 0 )
			goto cleanup_exit_error;

		dcc->state = LIBIRC_STATE_LISTENING;
	}
	else
	{
		// make socket non-blocking, so connect() call won't block
		if ( socket_make_nonblocking (&dcc->sock) )
			goto cleanup_exit_error;

		memset (&dcc->remote_addr, 0, sizeof(dcc->remote_addr));
		dcc->remote_addr.sin_family = AF_INET;
		dcc->remote_addr.sin_addr.s_addr = htonl (ip); // what idiot came up with idea to send IP address in host-byteorder?
        dcc->remote_addr.sin_port = htons(port);

		dcc->state = LIBIRC_STATE_INIT;
	}

	dcc->dccmode = dccmode;
	dcc->ctx = ctx;
	time (&dcc->timeout);

	// and store it
	libirc_mutex_lock (&session->mutex_dcc);

	dcc->id = session->dcc_last_id++;
	dcc->next = session->dcc_sessions;
	session->dcc_sessions = dcc;

	libirc_mutex_unlock (&session->mutex_dcc);

    *pdcc = dcc;
    return 0;

cleanup_exit_error:
	if ( dcc->sock >= 0 )
		socket_close (&dcc->sock);

	free (dcc);
	return LIBIRC_ERR_SOCKET;
}
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;

	// 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;
	}

	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);

	memset (&saddr, 0, sizeof(saddr));
	saddr.sin_family = AF_INET;
	saddr.sin_port = htons (port);
	saddr.sin_addr.s_addr = inet_addr (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 (server, &tmp_hostent, buf, sizeof(buf), &hp, &tmp_errno) )
      		hp = 0;
#else
      	hp = gethostbyname (server);
#endif
		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;
	}

    // 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->motd_received = 0; // reset in case of reconnect
	return 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];
#if defined (_WIN32)
	int addrlen = sizeof(saddr);
	HMODULE hWsock;
	getaddrinfo_ptr_t getaddrinfo_ptr;
	freeaddrinfo_ptr_t freeaddrinfo_ptr;
	int resolvesuccess = 0;
#endif // _WIN32
	sprintf(portStr, "%u", (unsigned)port);

	// 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;
	}

	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);

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

#if defined (_WIN32)
	if ( WSAStringToAddressA( (LPSTR)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(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, 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( server, portStr, &ainfo, &res ) || !res )
		{
			session->lasterror = LIBIRC_ERR_RESOLV;
			return 1;
		}
		
		memcpy( &saddr, res->ai_addr, res->ai_addrlen );
		freeaddrinfo( res );
	}
#endif // _WIN32
	
	// 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;
	}

    // 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->motd_received = 0; // reset in case of reconnect
	return 0;
#else
	session->lasterror = LIBIRC_ERR_NOIPV6;
	return 1;
#endif // ENABLE_IPV6
}
Esempio n. 5
0
static int libirc_new_dcc_session(irc_session_t * session, unsigned long ip, unsigned short port, void * ctx, irc_dcc_session_t ** pdcc, int ssl) {
    irc_dcc_session_t * dcc = malloc(sizeof (irc_dcc_session_t));

    if (!dcc)
        return LIBIRC_ERR_NOMEM;

    // setup
    memset(dcc, 0, sizeof (irc_dcc_session_t));

    dcc->dccsend_file_fp = 0;

    if (libirc_mutex_init(&dcc->mutex_outbuf))
        goto cleanup_exit_error;

    if (socket_create(PF_INET, SOCK_STREAM, &dcc->sock))
        goto cleanup_exit_error;

	// make socket non-blocking, so connect() call won't block
    if (socket_make_nonblocking(&dcc->sock))
        goto cleanup_exit_error;

    //optimizeSocketBufferSize(dcc);
 
#if defined (ENABLE_SSL)
    dcc->ssl = 0;
    if (ssl) {
        dcc->ssl = 1;
        if (!isSslIntitialized()) {
            DBG_OK("need to init ssl context!");
            int ret = initSslContext(session);
            if (ret != 0) {
                DBG_ERR("ssl context cant be inited!");
                exit(-1);
            }

        }
        dcc->ssl_ctx = SSL_new(ssl_context);
        SSL_set_fd(dcc->ssl_ctx, dcc->sock);
        if (session->verify_callback != NULL)
            SSL_set_verify(dcc->ssl_ctx, SSL_VERIFY_PEER, session->verify_callback);
        else
            SSL_set_verify(dcc->ssl_ctx, SSL_VERIFY_NONE, NULL);
        // Since we're connecting on our own, tell openssl about it
        SSL_set_connect_state(dcc->ssl_ctx);
    }
#endif

    memset(&dcc->remote_addr, 0, sizeof (dcc->remote_addr));
    dcc->remote_addr.sin_family = AF_INET;
    dcc->remote_addr.sin_addr.s_addr = htonl(ip); // what idiot came up with idea to send IP address in host-byteorder?
    dcc->remote_addr.sin_port = htons(port);

    dcc->state = LIBIRC_STATE_INIT;

    dcc->ctx = ctx;
    time(&dcc->timeout);

    // and store it
    libirc_mutex_lock(&session->mutex_dcc);

    dcc->id = session->dcc_last_id++;
    dcc->next = session->dcc_sessions;
    session->dcc_sessions = dcc;

    libirc_mutex_unlock(&session->mutex_dcc);

    *pdcc = dcc;
    return 0;

cleanup_exit_error:
    if (dcc->sock >= 0)
        socket_close(&dcc->sock);

    free(dcc);
    return LIBIRC_ERR_SOCKET;
}
Esempio n. 6
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
}
Esempio n. 7
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;
}