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