int OpenTelnetConnection(void) { int nReturn, ret; struct sockaddr_in sockaddr; char *p; static struct kstream_crypt_ctl_block ctl; char buf[128]; tmpConfig = calloc(sizeof(CONFIG), 1); if (bAutoConnection) { tmpConfig->title = calloc(lstrlen(szHostName), 1); lstrcpy(tmpConfig->title, (char *) szHostName); } else { nReturn = DoDialog("OPENTELNETDLG", OpenTelnetDlg); if (nReturn == FALSE) return(FALSE); } con = (CONNECTION *) GetNewConnection(); if (con == NULL) return(0); tmpConfig->width = GetPrivateProfileInt(INI_TELNET, INI_WIDTH, DEF_WIDTH, TELNET_INI); tmpConfig->height = GetPrivateProfileInt(INI_TELNET, INI_HEIGHT, DEF_HEIGHT, TELNET_INI); con->width = tmpConfig->width; con->height = tmpConfig->height; con->backspace = SaveHostName(tmpConfig->title, port_no); if (con->backspace == VK_BACK) { tmpConfig->backspace = TRUE; con->ctrl_backspace = 0x7f; } else { tmpConfig->backspace = FALSE; con->ctrl_backspace = 0x08; } tmpConfig->hwndTel = hWnd; con->pScreen = InitNewScreen(tmpConfig); if (!con->pScreen) { assert(FALSE); free(con->pScreen); free(con); free(tmpConfig); return(-1); } ret = (SOCKET) socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (ret == SOCKET_ERROR) { wsprintf(buf, "Socket error on socket = %d!", WSAGetLastError()); MessageBox(NULL, buf, NULL, MB_OK | MB_ICONEXCLAMATION); if (con->pScreen != NULL) DestroyWindow(con->pScreen->hWnd); free(con); free(tmpConfig); return(-1); } con->socket = ret; sockaddr.sin_family = AF_INET; sockaddr.sin_addr.s_addr = htonl(INADDR_ANY); sockaddr.sin_port = htons(0); ret = bind(con->socket, (struct sockaddr *) &sockaddr, (int) sizeof(struct sockaddr_in)); if (ret == SOCKET_ERROR) { wsprintf(buf, "Socket error on bind!"); MessageBox(NULL, buf, NULL, MB_OK | MB_ICONEXCLAMATION); if (con->pScreen != NULL) DestroyWindow(con->pScreen->hWnd); free(con); free(tmpConfig); return(-1); } WSAAsyncSelect(con->socket, hWnd, WM_NETWORKEVENT, FD_READ | FD_CLOSE | FD_CONNECT); lstrcpy(szHostName, tmpConfig->title); p = strchr(szHostName, '@'); if (p != NULL) { *p = 0; strcpy (szUserName, szHostName); strcpy(szHostName, ++p); } WSAAsyncGetHostByName(hWnd, WM_HOSTNAMEFOUND, szHostName, hostdata, MAXGETHOSTSTRUCT); ctl.encrypt = auth_encrypt; ctl.decrypt = auth_decrypt; ctl.init = auth_init; ctl.destroy = auth_destroy; con->ks = kstream_create_from_fd(con->socket, &ctl, NULL); if (con->ks == NULL) return(-1); kstream_set_buffer_mode(con->ks, 0); return(1); }
void EnterListener(struct ListenerOptions *opts) { /* master file descriptor list */ fd_set master; /* temp file descriptor list for select() */ fd_set read_fds; /* maximum file descriptor number */ int fdmax; /* listening socket descriptor */ int listener; /* for setsockopt() SO_REUSEADDR, below */ int yes = 1; int j; struct addrinfo *result, *rp; /* clear the master and temp sets */ FD_ZERO(&master); FD_ZERO(&read_fds); memset(&opts->hints, 0, sizeof(struct addrinfo)); opts->hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */ opts->hints.ai_socktype = SOCK_STREAM; /* Datagram socket */ opts->hints.ai_flags = AI_PASSIVE; j = getaddrinfo(opts->nodename, opts->servname, &opts->hints, &result); if (j != 0) { fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(j)); exit(EXIT_FAILURE); } /* getaddrinfo() returns a list of address structures. Try each address until we successfully bind(2). If socket(2) (or bind(2)) fails, we (close the socket and) try the next address. */ for (rp = result; rp != NULL ; rp = rp->ai_next) { listener = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); if (listener == -1) continue; /*"address already in use" error message */ if (setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) goto tryagain; #ifdef SO_REUSEPORT if (setsockopt(listener, SOL_SOCKET, SO_REUSEPORT, &yes, sizeof(int)) == -1) goto tryagain; #endif if (bind(listener, rp->ai_addr, rp->ai_addrlen) == 0) break; /* Success */ tryagain: close(listener); } if (rp == NULL ) { /* No address succeeded */ fprintf(stderr, "Could not bind\n"); exit(EXIT_FAILURE); } freeaddrinfo(result); /* No longer needed */ /* listen */ if (listen(listener, SOMAXCONN) == -1) { perror("Error opening listener"); exit(1); } /* add the listener to the master set */ FD_SET(listener, &master); /* keep track of the biggest file descriptor */ fdmax = listener; /* so far, it's this one */ /* loop */ for (;;) { /* copy it */ read_fds = master; if (select(fdmax + 1, &read_fds, NULL, NULL, NULL ) == -1) { perror("Error waiting for input"); exit(1); } if (FD_ISSET(listener, &read_fds)) { /* we got a new one... */ /* handle new connections */ struct ConnectionNode *TempNode = GetNewConnection(); TempNode->addr_len = sizeof(TempNode->addr); if ((TempNode->fd = accept(listener, (struct sockaddr *) &TempNode->addr, &TempNode->addr_len)) == -1) { perror("Warning accepting one new connection"); free(TempNode); } else { FD_SET(TempNode->fd, &master); /* add to master set */ fdmax = TempNode->fd; fdmax = TempNode->fd; j = getnameinfo((struct sockaddr *) &TempNode->addr, TempNode->addr_len, TempNode->host, NI_MAXHOST, NULL, 0, 0); InsertConnectionBefore(&connections_head, TempNode); printf("New connection from %s on socket %d index %d\n", TempNode->host, TempNode->fd, TempNode->index); } } /* run through the existing connections looking for data to be read */ struct ConnectionNode *i = connections_head; if (connections_head != NULL ) do { if (FD_ISSET(i->fd, &read_fds)) { /* we got one... */ /* handle data from a client */ printf("New data from %s on socket %d index %d\n", i->host, i->fd, i->index); /* buffer for client data */ char buf[1024]; int nbytes; if ((nbytes = recv(i->fd, buf, sizeof(buf) - 1, 0)) <= 0) { /* got error or connection closed by client */ if (nbytes == 0) /* connection closed */ printf( "socket to %s hung up on socket %d index %d\n", i->host, i->fd, i->index); else perror("Negative recv"); /* close it... */ close(i->fd); /* remove from master set */ FD_CLR(i->fd, &master); /* step back and remove this connection */ i = RemoveConnection(i); if (i == NULL ) break; } else { /* Ensure this is an ansi string */ buf[nbytes] = '\0'; ProccessInput(i, buf, nbytes); } } i = i->next; } while (i != connections_head); } }