/* complete the connection to the IRC server */ static unsigned int connectirc2(res_addrinfo_t *remote) { int retval; int family; if (remote->ai_reset) gnetwork->serv_resolv.next = 0; family = remote->ai_addr.sa_family; gnetwork->ircserver = socket(family, remote->ai_socktype, remote->ai_protocol); if (gnetwork->ircserver < 0) { outerror(OUTERROR_TYPE_WARN_LOUD, "Socket Error: %s", strerror(errno)); return 1; } if (gdata.debug > 0) { char *msg; msg = mymalloc(maxtextlength); my_getnameinfo(msg, maxtextlength -1, &(remote->ai_addr)); ioutput(OUT_S, COLOR_YELLOW, "Connecting to %s", msg); mydelete(msg); } if (bind_irc_vhost(family, gnetwork->ircserver) != 0) { outerror(OUTERROR_TYPE_WARN_LOUD, "Couldn't Bind To Virtual Host"); event_close(gnetwork->ircserver); return 1; } if (set_socket_nonblocking(gnetwork->ircserver, 1) < 0 ) outerror(OUTERROR_TYPE_WARN, "Couldn't Set Non-Blocking"); alarm(CTIMEOUT); retval = connect(gnetwork->ircserver, &(remote->ai_addr), remote->ai_addrlen); if ( (retval < 0) && !((errno == EINPROGRESS) || (errno == EAGAIN)) ) { outerror(OUTERROR_TYPE_WARN_LOUD, "Connection to Server Failed: %s", strerror(errno)); alarm(0); event_close(gnetwork->ircserver); return 1; } alarm(0); if (gdata.debug > 0) { ioutput(OUT_S, COLOR_YELLOW, "ircserver socket = %d", gnetwork->ircserver); } gnetwork->lastservercontact=gdata.curtime; /* good */ gnetwork->serverstatus = SERVERSTATUS_TRYING; return 0; }
static void t_passive(transfer * const tr, ir_uint16 remoteport) { char *msg; ir_uint32 netval; SIGNEDSOCK int addrlen; int retval; updatecontext(); bzero ((char *) &(tr->con.remote), sizeof(tr->con.remote)); tr->con.clientsocket = socket(tr->con.family, SOCK_STREAM, 0); if (tr->con.clientsocket < 0) { t_closeconn(tr, "Socket Error", errno); return; } if (tr->con.family == AF_INET ) { addrlen = sizeof(struct sockaddr_in); tr->con.remote.sin.sin_family = AF_INET; tr->con.remote.sin.sin_port = htons(remoteport); netval = atoul(tr->con.remoteaddr); tr->con.remote.sin.sin_addr.s_addr = htonl(netval); } else { addrlen = sizeof(struct sockaddr_in6); tr->con.remote.sin6.sin6_family = AF_INET6; tr->con.remote.sin6.sin6_port = htons(remoteport); retval = inet_pton(AF_INET6, tr->con.remoteaddr, &(tr->con.remote.sin6.sin6_addr)); if (retval < 0) outerror(OUTERROR_TYPE_WARN_LOUD, "Invalid IP: %s", tr->con.remoteaddr); } if (t_check_ip_access(tr)) return; if (bind_irc_vhost(tr->con.family, tr->con.clientsocket) != 0) { t_closeconn(tr, "Couldn't Bind Virtual Host, Sorry", errno); return; } if (set_socket_nonblocking(tr->con.clientsocket, 1) < 0 ) { outerror(OUTERROR_TYPE_WARN, "Couldn't Set Non-Blocking"); } if (gdata.debug > 0) { msg = mymalloc(maxtextlength); my_getnameinfo(msg, maxtextlength -1, &(tr->con.remote.sa)); ioutput(OUT_S|OUT_L|OUT_D, COLOR_MAGENTA, "DCC SEND passive sent to %s on %s, connecting to %s", tr->nick, gnetwork->name, msg); mydelete(msg); } alarm(CTIMEOUT); retval = connect(tr->con.clientsocket, &(tr->con.remote.sa), addrlen); if ( (retval < 0) && !((errno == EINPROGRESS) || (errno == EAGAIN)) ) { t_closeconn(tr, "Couldn't Connect", errno); alarm(0); return; } alarm(0); tr->tr_status = TRANSFER_STATUS_CONNECTING; }
int setupdccchat(const char *nick, const char *hostmask, const char *line) { char *ip, *port; SIGNEDSOCK int addrlen; int retval; dccchat_t *chat; char *msg; updatecontext(); ip = getpart(line,7); port = getpart(line,8); if ( !ip || !port ) { mydelete(ip); mydelete(port); return 1; } /* support passive dcc */ if (strcmp(port, "0") == 0) { char *token; mydelete(ip); mydelete(port); if (gdata.passive_dcc_chat) { token = getpart(line, 9); setupdccchatout(nick, hostmask, token); mydelete(token); } else { notice(nick, "DCC passive Chat denied, use \"/MSG %s ADMIN password CHATME\" instead.", get_user_nick()); ioutput(OUT_S|OUT_L|OUT_D, COLOR_MAGENTA, "DCC CHAT attempt denied from %s (%s on %s)", nick, hostmask, gnetwork->name); } return 1; } chat = irlist_add(&gdata.dccchats, sizeof(dccchat_t)); chat->name = gnetwork->name; bzero((char *) &(chat->con.remote), sizeof(chat->con.remote)); chat->con.family = (strchr(ip, ':')) ? AF_INET6 : AF_INET; chat->con.clientsocket = socket(chat->con.family, SOCK_STREAM, 0); if (chat->con.clientsocket < 0) { outerror(OUTERROR_TYPE_WARN_LOUD,"Socket Error: %s", strerror(errno)); chat->con.clientsocket = FD_UNUSED; mydelete(ip); mydelete(port); return 1; } port[strlen(port)-1] = '\0'; if (chat->con.family == AF_INET) { addrlen = sizeof(struct sockaddr_in); chat->con.remote.sin.sin_family = AF_INET; chat->con.remote.sin.sin_port = htons(atoi(port)); chat->con.remote.sin.sin_addr.s_addr = htonl(atoul(ip)); } else { addrlen = sizeof(struct sockaddr_in6); chat->con.remote.sin6.sin6_family = AF_INET6; chat->con.remote.sin6.sin6_port = htons(atoi(port)); retval = inet_pton(AF_INET6, ip, &(chat->con.remote.sin6.sin6_addr)); if (retval != 0) outerror(OUTERROR_TYPE_WARN_LOUD, "Invalid IP: %s", ip); } mydelete(port); mydelete(ip); if (is_in_badip(&(chat->con.remote))) { shutdowndccchat(chat, 0); return 1; } if (bind_irc_vhost(chat->con.family, chat->con.clientsocket) != 0) { outerror(OUTERROR_TYPE_WARN_LOUD, "Couldn't Bind To Virtual Host: %s", strerror(errno)); chat->con.clientsocket = FD_UNUSED; return 1; } if (set_socket_nonblocking(chat->con.clientsocket, 1) < 0 ) { outerror(OUTERROR_TYPE_WARN,"Couldn't Set Non-Blocking"); } alarm(CTIMEOUT); retval = connect(chat->con.clientsocket, &(chat->con.remote.sa), addrlen); if ((retval < 0) && !((errno == EINPROGRESS) || (errno == EAGAIN))) { outerror(OUTERROR_TYPE_WARN_LOUD,"Connection to DCC Chat Failed: %s", strerror(errno)); chat->con.clientsocket = FD_UNUSED; return 1; } alarm(0); addrlen = sizeof(chat->con.local); if (getsockname(chat->con.clientsocket, &(chat->con.local.sa), &addrlen) < 0) { outerror(OUTERROR_TYPE_WARN_LOUD,"Couldn't get sock name: %s", strerror(errno)); chat->con.clientsocket = FD_UNUSED; return 1; } if (gdata.debug > 0) { ioutput(OUT_S, COLOR_YELLOW, "dccchat socket = %d", chat->con.clientsocket); } gdata.num_dccchats++; chat->status = DCCCHAT_CONNECTING; chat->nick = mystrdup(nick); chat->hostmask = mystrdup(hostmask); chat->con.localport = 0; chat->con.connecttime = gdata.curtime; chat->con.lastcontact = gdata.curtime; chat->net = gnetwork->net; msg = mymalloc(maxtextlength); my_getnameinfo(msg, maxtextlength -1, &(chat->con.local.sa)); chat->con.localaddr = mystrdup(msg); my_getnameinfo(msg, maxtextlength -1, &(chat->con.remote.sa)); chat->con.remoteaddr = mystrdup(msg); mydelete(msg); ioutput(OUT_S|OUT_L|OUT_D, COLOR_MAGENTA, "DCC CHAT received from %s on %s, attempting connection to %s", nick, chat->name, chat->con.remoteaddr); return 0; }