int main(int argc, char *argv[]) { FILE *fp; int ch; char *lp; struct sockaddr_storage ss; socklen_t sval; int p[2], debug, kflag, logging, pflag, secure; #define ENTRIES 50 char **ap, *av[ENTRIES + 1], **comp, line[1024], *prog; char rhost[MAXHOSTNAMELEN]; prog = _PATH_FINGER; debug = logging = kflag = pflag = secure = 0; openlog("fingerd", LOG_PID | LOG_CONS, LOG_DAEMON); opterr = 0; while ((ch = getopt(argc, argv, "dklp:s")) != -1) switch (ch) { case 'd': debug = 1; break; case 'k': kflag = 1; break; case 'l': logging = 1; break; case 'p': prog = optarg; pflag = 1; break; case 's': secure = 1; break; case '?': default: logerr("illegal option -- %c", optopt); } /* * Enable server-side Transaction TCP. */ if (!debug) { int one = 1; if (setsockopt(STDOUT_FILENO, IPPROTO_TCP, TCP_NOPUSH, &one, sizeof one) < 0) { logerr("setsockopt(TCP_NOPUSH) failed: %m"); } } if (!fgets(line, sizeof(line), stdin)) exit(1); if (!debug && (logging || pflag)) { sval = sizeof(ss); if (getpeername(0, (struct sockaddr *)&ss, &sval) < 0) logerr("getpeername: %s", strerror(errno)); realhostname_sa(rhost, sizeof rhost - 1, (struct sockaddr *)&ss, sval); rhost[sizeof(rhost) - 1] = '\0'; if (pflag) setenv("FINGERD_REMOTE_HOST", rhost, 1); } if (logging) { char *t; char *end; end = memchr(line, 0, sizeof(line)); if (end == NULL) { if ((t = malloc(sizeof(line) + 1)) == NULL) logerr("malloc: %s", strerror(errno)); memcpy(t, line, sizeof(line)); t[sizeof(line)] = 0; } else { if ((t = strdup(line)) == NULL) logerr("strdup: %s", strerror(errno)); } for (end = t; *end; end++) if (*end == '\n' || *end == '\r') *end = ' '; syslog(LOG_NOTICE, "query from %s: `%s'", rhost, t); } comp = &av[2]; av[3] = "--"; if (kflag) *comp-- = "-k"; for (lp = line, ap = &av[4];;) { *ap = strtok(lp, " \t\r\n"); if (!*ap) { if (secure && ap == &av[4]) { #ifdef USE_BLACKLIST blacklist(1, STDIN_FILENO, "nousername"); #endif puts("must provide username\r\n"); exit(1); } break; } if (secure && strchr(*ap, '@')) { #ifdef USE_BLACKLIST blacklist(1, STDIN_FILENO, "noforwarding"); #endif puts("forwarding service denied\r\n"); exit(1); } /* RFC742: "/[Ww]" == "-l" */ if ((*ap)[0] == '/' && ((*ap)[1] == 'W' || (*ap)[1] == 'w')) { *comp-- = "-l"; } else if (++ap == av + ENTRIES) { *ap = NULL; break; } lp = NULL; } if ((lp = strrchr(prog, '/')) != NULL) *comp = ++lp; else *comp = prog; if (pipe(p) < 0) logerr("pipe: %s", strerror(errno)); if (debug) { fprintf(stderr, "%s", prog); for (ap = comp; *ap != NULL; ++ap) fprintf(stderr, " %s", *ap); fprintf(stderr, "\n"); } switch(vfork()) { case 0: (void)close(p[0]); if (p[1] != STDOUT_FILENO) { (void)dup2(p[1], STDOUT_FILENO); (void)close(p[1]); } dup2(STDOUT_FILENO, STDERR_FILENO); #ifdef USE_BLACKLIST blacklist(0, STDIN_FILENO, "success"); #endif execv(prog, comp); write(STDERR_FILENO, prog, strlen(prog)); #define MSG ": cannot execute\n" write(STDERR_FILENO, MSG, strlen(MSG)); #undef MSG _exit(1); case -1: logerr("fork: %s", strerror(errno)); } (void)close(p[1]); if (!(fp = fdopen(p[0], "r"))) logerr("fdopen: %s", strerror(errno)); while ((ch = getc(fp)) != EOF) { if (ch == '\n') putchar('\r'); putchar(ch); } exit(0); }
void server_process(struct pollfd *fds, int num) { int i = 0; for(i = 0; i < server_max_pollfd; ++i) { if(fds[i].revents == 0) { continue; } if(fds[i].fd == sock_fd) { if(fds[i].revents & POLLIN) { int data_fd; struct sockaddr_in clnt; int clnt_len = sizeof(clnt); memset(&clnt, 0, sizeof(clnt)); if((data_fd = accept(sock_fd, (struct sockaddr*)&clnt, &clnt_len)) < 0) { perror("accept"); } char clnt_addr[16] = ""; inet_ntop(AF_INET, &clnt.sin_addr, clnt_addr, sizeof(clnt_addr)); printf("[%s] connected\n", clnt_addr); poll_add(data_fd); } if(fds[i].revents & POLLERR) { printf("error occured\n"); } if(fds[i].revents & POLLNVAL) { printf("invalid request\n"); } } else { if(fds[i].revents & POLLIN) { char clnt_addr[16] = ""; struct sockaddr_in clnt; int clnt_len = sizeof(clnt); if(getpeername(fds[i].fd, (struct sockaddr*)&clnt, &clnt_len) < 0) { perror("getpeername"); } inet_ntop(AF_INET, &clnt.sin_addr, clnt_addr, sizeof(clnt_addr)); int recv_data = 0; int recv_cnt = 0; recv_cnt = recv(fds[i].fd, &recv_data, sizeof(recv_data), 0); if(recv_cnt > 0) { printf("receive [%d] from [%s]\n", recv_data, clnt_addr); } else if(recv_cnt == 0) { printf("[%s] disconnected\n\n", clnt_addr); close(fds[i].fd); poll_remove(i); } else if(recv_cnt == -1) { perror("recv"); } } if(fds[i].revents & POLLOUT) { printf("ready to write data\n"); } if(fds[i].revents & POLLERR) { printf("error occured\n"); } if(fds[i].revents & POLLNVAL) { printf("invalid request\n"); } if(fds[i].revents & POLLHUP) { printf("pollhup\n"); } if(fds[i].revents & POLLRDHUP) { printf("pollrdhup\n"); } } } }
int RTSP_setup(RTSP_buffer * rtsp, RTSP_session ** new_session) { char address[16]; char object[255], server[255]; char url[255]; unsigned short port; RTSP_session *rtsp_s; RTP_session *rtp_s, *rtp_s_prec; int SessionID = 0; // port_pair cli_ports; // port_pair ser_ports; struct timeval now_tmp; char *p/* = NULL*/; unsigned int start_seq, start_rtptime; char transport_str[255]; media_entry *list, *matching_me, req; struct sockaddr_storage rtsp_peer; socklen_t namelen = sizeof(rtsp_peer); unsigned long ssrc; SD_descr *matching_descr; unsigned char is_multicast_dad = 1; //unicast and the first multicast RTP_transport transport; char *saved_ptr, *transport_tkn; int max_interlvd; // init memset(&req, 0, sizeof(req)); memset(&transport, 0, sizeof(transport)); // Parse the input message /* Get the URL */ if (!sscanf(rtsp->in_buffer, " %*s %254s ", url)) { send_reply(400, 0, rtsp); /* bad request */ return ERR_NOERROR; } /* Validate the URL */ switch (parse_url(url, server, sizeof(server), &port, object, sizeof(object))) { //object is requested file's name case 1: // bad request send_reply(400, 0, rtsp); return ERR_NOERROR; case -1: // interanl server error send_reply(500, 0, rtsp); return ERR_NOERROR; break; default: break; } if (strcmp(server, prefs_get_hostname()) != 0) { /* Currently this feature is disabled. */ /* wrong server name */ // send_reply(404, 0 , rtsp); /* Not Found */ // return ERR_NOERROR; } if (strstr(object, "../")) { /* disallow relative paths outside of current directory. */ send_reply(403, 0, rtsp); /* Forbidden */ return ERR_NOERROR; } if (strstr(object, "./")) { /* Disallow the ./ */ send_reply(403, 0, rtsp); /* Forbidden */ return ERR_NOERROR; } if (!(p = strrchr(object, '.'))) { // if filename is without extension send_reply(415, 0, rtsp); /* Unsupported media type */ return ERR_NOERROR; } else if (!is_supported_url(p)) { //if filename's extension is not valid send_reply(415, 0, rtsp); /* Unsupported media type */ return ERR_NOERROR; } if ( !(p = strchr(object, '!')) ) { //if '!' is not present then a file has not been specified send_reply(500, 0, rtsp); /* Internal server error */ return ERR_NOERROR; } else { // SETUP name.sd!stream strcpy(req.filename, p + 1); req.flags |= ME_FILENAME; *p = '\0'; } // ------------ START PATCH { char temp[255]; char *pd=NULL; strcpy(temp, object); #if 0 printf("%s\n", object); // BEGIN // if ( (p = strstr(temp, "/")) ) { if ( (p = strchr(temp, '/')) ) { strcpy(object, p + 1); // CRITIC. } printf("%s\n", temp); #endif // pd = strstr(p, ".sd"); // this part is usefull in order to pd = strstr(temp, ".sd"); if ( (p = strstr(pd + 1, ".sd")) ) { // have compatibility with RealOne strcpy(object, pd + 4); // CRITIC. } //Note: It's a critic part // END } // ------------ END PATCH if (enum_media(object, &matching_descr) != ERR_NOERROR) { send_reply(500, 0, rtsp); /* Internal server error */ return ERR_NOERROR; } list=matching_descr->me_list; if (get_media_entry(&req, list, &matching_me) == ERR_NOT_FOUND) { send_reply(404, 0, rtsp); /* Not found */ return ERR_NOERROR; } // Get the CSeq if ((p = strstr(rtsp->in_buffer, HDR_CSEQ)) == NULL) { send_reply(400, 0, rtsp); /* Bad Request */ return ERR_NOERROR; } else { if (sscanf(p, "%*s %d", &(rtsp->rtsp_cseq)) != 1) { send_reply(400, 0, rtsp); /* Bad Request */ return ERR_NOERROR; } } /*if ((p = strstr(rtsp->in_buffer, "ssrc")) != NULL) { p = strchr(p, '='); sscanf(p + 1, "%lu", &ssrc); } else {*/ ssrc = random32(0); //} // Start parsing the Transport header if ((p = strstr(rtsp->in_buffer, HDR_TRANSPORT)) == NULL) { send_reply(406, "Require: Transport settings" /* of rtp/udp;port=nnnn. "*/, rtsp); /* Not Acceptable */ return ERR_NOERROR; } if (sscanf(p, "%*10s%255s", transport_str) != 1) { fnc_log(FNC_LOG_ERR,"SETUP request malformed: Transport string is empty\n"); send_reply(400, 0, rtsp); /* Bad Request */ return ERR_NOERROR; } printf("transport: %s\n", transport_str); // XXX tmp. // tokenize the coma seaparated list of transport settings: if ( !(transport_tkn=strtok_r(transport_str, ",", &saved_ptr)) ) { fnc_log(FNC_LOG_ERR,"Malformed Transport string from client\n"); send_reply(400, 0, rtsp); /* Bad Request */ return ERR_NOERROR; } if (getpeername(rtsp->fd, (struct sockaddr *)&rtsp_peer, &namelen) != 0) { send_reply(415, 0, rtsp); // Internal server error return ERR_GENERIC; } transport.type = RTP_no_transport; do { // search a good transport string if ( (p = strstr(transport_tkn, RTSP_RTP_AVP)) ) { // Transport: RTP/AVP p += strlen(RTSP_RTP_AVP); if ( !*p || (*p == ';') || (*p == ' ')) { #if 0 // if ((p = strstr(rtsp->in_buffer, "client_port")) == NULL && strstr(rtsp->in_buffer, "multicast") == NULL) { if ((p = strstr(transport_tkn, "client_port")) == NULL && strstr(transport_tkn, "multicast") == NULL) { send_reply(406, "Require: Transport settings of rtp/udp;port=nnnn. ", rtsp); /* Not Acceptable */ return ERR_NOERROR; } #endif // #if 0 if (strstr(transport_tkn, "unicast")) { if( (p = strstr(transport_tkn, "client_port")) ) { p = strstr(p, "="); sscanf(p + 1, "%d", &(transport.u.udp.cli_ports.RTP)); p = strstr(p, "-"); sscanf(p + 1, "%d", &(transport.u.udp.cli_ports.RTCP)); } if (RTP_get_port_pair(&transport.u.udp.ser_ports) != ERR_NOERROR) { send_reply(500, 0, rtsp); /* Internal server error */ return ERR_GENERIC; } // strcpy(address, get_address()); //UDP connection for outgoing RTP packets udp_connect(transport.u.udp.cli_ports.RTP, &transport.u.udp.rtp_peer, (*((struct sockaddr_in *) (&rtsp_peer))).sin_addr.s_addr,&transport.rtp_fd); //UDP connection for outgoing RTCP packets udp_connect(transport.u.udp.cli_ports.RTCP, &transport.u.udp.rtcp_out_peer,(*((struct sockaddr_in *) (&rtsp_peer))).sin_addr.s_addr, &transport.rtcp_fd_out); udp_open(transport.u.udp.ser_ports.RTCP, &transport.u.udp.rtcp_in_peer, &transport.rtcp_fd_in); //bind transport.u.udp.is_multicast = 0; } else if ( matching_descr->flags & SD_FL_MULTICAST ) { /*multicast*/ // TODO: make the difference between only multicast allowed or unicast fallback allowed. transport.u.udp.cli_ports.RTP = transport.u.udp.ser_ports.RTP =matching_me->rtp_multicast_port; transport.u.udp.cli_ports.RTCP = transport.u.udp.ser_ports.RTCP =matching_me->rtp_multicast_port+1; is_multicast_dad = 0; if (!(matching_descr->flags & SD_FL_MULTICAST_PORT) ) { struct in_addr inp; unsigned char ttl=DEFAULT_TTL; struct ip_mreq mreq; mreq.imr_multiaddr.s_addr = inet_addr(matching_descr->multicast); mreq.imr_interface.s_addr = INADDR_ANY; setsockopt(transport.rtp_fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)); setsockopt(transport.rtp_fd, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl)); is_multicast_dad = 1; strcpy(address, matching_descr->multicast); //RTP outgoing packets inet_aton(address, &inp); udp_connect(transport.u.udp.ser_ports.RTP, &transport.u.udp.rtp_peer, inp.s_addr, &transport.rtp_fd); //RTCP outgoing packets inet_aton(address, &inp); udp_connect(transport.u.udp.ser_ports.RTCP, &transport.u.udp.rtcp_out_peer, inp.s_addr, &transport.rtcp_fd_out); //udp_open(transport.u.udp.ser_ports.RTCP, &(sp2->rtcp_in_peer), &(sp2->rtcp_fd_in)); //bind if(matching_me->next==NULL) matching_descr->flags |= SD_FL_MULTICAST_PORT; matching_me->rtp_multicast_port = transport.u.udp.ser_ports.RTP; transport.u.udp.is_multicast = 1; fnc_log(FNC_LOG_DEBUG,"\nSet up socket for multicast ok\n"); } } else continue; transport.type = RTP_rtp_avp; break; // found a valid transport } else if (!strncmp(p, "/TCP", 4)) { // Transport: RTP/AVP/TCP;interleaved=x-y // XXX still not finished if( (p = strstr(transport_tkn, "interleaved")) ) { p = strstr(p, "="); sscanf(p + 1, "%d", &(transport.u.tcp.interleaved.RTP)); if ( (p = strstr(p, "-")) ) sscanf(p + 1, "%d", &(transport.u.tcp.interleaved.RTCP)); else transport.u.tcp.interleaved.RTCP = transport.u.tcp.interleaved.RTP + 1; } else { // search for max used interleved channel. max_interlvd = -1; for (rtp_s = (rtsp->session_list)?rtsp->session_list->rtp_session:NULL; rtp_s; rtp_s = rtp_s->next) max_interlvd = max(max_interlvd, (rtp_s->transport.type == RTP_rtp_avp_tcp)?rtp_s->transport.u.tcp.interleaved.RTCP:-1); transport.u.tcp.interleaved.RTP = max_interlvd + 1; transport.u.tcp.interleaved.RTCP = max_interlvd + 2; } transport.rtp_fd = rtsp->fd; // dup(rtsp->fd); transport.rtcp_fd_out = rtsp->fd; // dup(rtsp->fd); transport.rtcp_fd_in = -1; transport.type = RTP_rtp_avp_tcp; break; // found a valid transport } } } while ((transport_tkn=strtok_r(NULL, ",", &saved_ptr))); printf("rtp transport: %d\n", transport.type); if (transport.type == RTP_no_transport) { // fnc_log(FNC_LOG_ERR,"Unsupported Transport\n"); send_reply(461, "Unsupported Transport", rtsp); /* Bad Request */ return ERR_NOERROR; } // If there's a Session header we have an aggregate control if ((p = strstr(rtsp->in_buffer, HDR_SESSION)) != NULL) { if (sscanf(p, "%*s %d", &SessionID) != 1) { send_reply(454, 0, rtsp); /* Session Not Found */ return ERR_NOERROR; } } else { // Generate a random Session number gettimeofday(&now_tmp, 0); srand((now_tmp.tv_sec * 1000) + (now_tmp.tv_usec / 1000)); #ifdef WIN32 SessionID = rand(); #else SessionID = 1 + (int) (10.0 * rand() / (100000 + 1.0)); #endif if (SessionID == 0) { SessionID++; } } // Add an RTSP session if necessary if ( !rtsp->session_list ) { rtsp->session_list = (RTSP_session *) calloc(1, sizeof(RTSP_session)); } rtsp_s = rtsp->session_list; // Setup the RTP session if (rtsp->session_list->rtp_session == NULL) { rtsp->session_list->rtp_session = (RTP_session *) calloc(1, sizeof(RTP_session)); rtp_s = rtsp->session_list->rtp_session; } else { for (rtp_s = rtsp_s->rtp_session; rtp_s != NULL; rtp_s = rtp_s->next) { rtp_s_prec = rtp_s; } rtp_s_prec->next = (RTP_session *) calloc(1, sizeof(RTP_session)); rtp_s = rtp_s_prec->next; } #ifdef WIN32 start_seq = rand(); start_rtptime = rand(); #else // start_seq = 1 + (int) (10.0 * rand() / (100000 + 1.0)); // start_rtptime = 1 + (int) (10.0 * rand() / (100000 + 1.0)); #if 0 start_seq = 1 + (unsigned int) ((float)(0xFFFF) * ((float)rand() / (float)RAND_MAX)); start_rtptime = 1 + (unsigned int) ((float)(0xFFFFFFFF) * ((float)rand() / (float)RAND_MAX)); #else start_seq = 1 + (unsigned int) (rand()%(0xFFFF)); start_rtptime = 1 + (unsigned int) (rand()%(0xFFFFFFFF)); #endif #endif if (start_seq == 0) { start_seq++; } if (start_rtptime == 0) { start_rtptime++; } rtp_s->pause = 1; strcpy(rtp_s->sd_filename, object); /*xxx*/ rtp_s->current_media = (media_entry *) calloc(1, sizeof(media_entry)); // if(!(matching_descr->flags & SD_FL_MULTICAST_PORT)){ if( is_multicast_dad ) { if ( mediacpy(&rtp_s->current_media, &matching_me) ) { send_reply(500, 0, rtsp); /* Internal server error */ return ERR_GENERIC; } } gettimeofday(&now_tmp, 0); srand((now_tmp.tv_sec * 1000) + (now_tmp.tv_usec / 1000)); rtp_s->start_rtptime = start_rtptime; rtp_s->start_seq = start_seq; memcpy(&rtp_s->transport, &transport, sizeof(transport)); rtp_s->is_multicast_dad = is_multicast_dad; /*xxx*/ rtp_s->sd_descr=matching_descr; rtp_s->sched_id = schedule_add(rtp_s); rtp_s->ssrc = ssrc; // Setup the RTSP session rtsp_s->session_id = SessionID; *new_session = rtsp_s; fnc_log(FNC_LOG_INFO,"SETUP %s RTSP/1.0 ",url); send_setup_reply(rtsp, rtsp_s, matching_descr, rtp_s); // See User-Agent if ((p=strstr(rtsp->in_buffer, HDR_USER_AGENT))!=NULL) { char cut[strlen(p)]; strcpy(cut,p); p=strstr(cut, "\n"); cut[strlen(cut)-strlen(p)-1]='\0'; fnc_log(FNC_LOG_CLIENT,"%s\n",cut); } else fnc_log(FNC_LOG_CLIENT,"- \n"); return ERR_NOERROR; }
/* oh, the humanity! */ static int ev_pipe (int filedes [2]) { struct sockaddr_in addr = { 0 }; int addr_size = sizeof (addr); struct sockaddr_in adr2; int adr2_size = sizeof (adr2); SOCKET listener; SOCKET sock [2] = { -1, -1 }; if ((listener = socket (AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) return -1; addr.sin_family = AF_INET; addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK); addr.sin_port = 0; if (bind (listener, (struct sockaddr *)&addr, addr_size)) goto fail; if (getsockname (listener, (struct sockaddr *)&addr, &addr_size)) goto fail; if (listen (listener, 1)) goto fail; if ((sock [0] = socket (AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) goto fail; if (connect (sock [0], (struct sockaddr *)&addr, addr_size)) goto fail; if ((sock [1] = accept (listener, 0, 0)) < 0) goto fail; /* windows vista returns fantasy port numbers for sockets: * example for two interconnected tcp sockets: * * (Socket::unpack_sockaddr_in getsockname $sock0)[0] == 53364 * (Socket::unpack_sockaddr_in getpeername $sock0)[0] == 53363 * (Socket::unpack_sockaddr_in getsockname $sock1)[0] == 53363 * (Socket::unpack_sockaddr_in getpeername $sock1)[0] == 53365 * * wow! tridirectional sockets! * * this way of checking ports seems to work: */ if (getpeername (sock [0], (struct sockaddr *)&addr, &addr_size)) goto fail; if (getsockname (sock [1], (struct sockaddr *)&adr2, &adr2_size)) goto fail; errno = WSAEINVAL; if (addr_size != adr2_size || addr.sin_addr.s_addr != adr2.sin_addr.s_addr /* just to be sure, I mean, it's windows */ || addr.sin_port != adr2.sin_port) goto fail; closesocket (listener); #if EV_SELECT_IS_WINSOCKET filedes [0] = EV_WIN32_HANDLE_TO_FD (sock [0]); filedes [1] = EV_WIN32_HANDLE_TO_FD (sock [1]); #else /* when select isn't winsocket, we also expect socket, connect, accept etc. * to work on fds */ filedes [0] = sock [0]; filedes [1] = sock [1]; #endif return 0; fail: closesocket (listener); if (sock [0] != INVALID_SOCKET) closesocket (sock [0]); if (sock [1] != INVALID_SOCKET) closesocket (sock [1]); return -1; }
int main(int argc, char *argv[]) { u_long ultmp; struct sockaddr_storage from; int on = 1, fromlen; int ch; #if defined(IPPROTO_IP) && defined(IP_TOS) int tos = -1; #endif char *ep; pfrontp = pbackp = ptyobuf; netip = netibuf; nfrontp = nbackp = netobuf; #ifdef ENCRYPTION nclearto = 0; #endif /* ENCRYPTION */ /* * This initialization causes linemode to default to a configuration * that works on all telnet clients, including the FreeBSD client. * This is not quite the same as the telnet client issuing a "mode * character" command, but has most of the same benefits, and is * preferable since some clients (like usofts) don't have the * mode character command anyway and linemode breaks things. * The most notable symptom of fix is that csh "set filec" operations * like <ESC> (filename completion) and ^D (choices) keys now work * in telnet sessions and can be used more than once on the same line. * CR/LF handling is also corrected in some termio modes. This * change resolves problem reports bin/771 and bin/1037. */ linemode=1; /*Default to mode that works on bulk of clients*/ while ((ch = getopt(argc, argv, valid_opts)) != -1) { switch(ch) { #ifdef AUTHENTICATION case 'a': /* * Check for required authentication level */ if (strcmp(optarg, "debug") == 0) { extern int auth_debug_mode; auth_debug_mode = 1; } else if (strcasecmp(optarg, "none") == 0) { auth_level = 0; } else if (strcasecmp(optarg, "other") == 0) { auth_level = AUTH_OTHER; } else if (strcasecmp(optarg, "user") == 0) { auth_level = AUTH_USER; } else if (strcasecmp(optarg, "valid") == 0) { auth_level = AUTH_VALID; } else if (strcasecmp(optarg, "off") == 0) { /* * This hack turns off authentication */ auth_level = -1; } else { warnx("unknown authorization level for -a"); } break; #endif /* AUTHENTICATION */ #ifdef BFTPDAEMON case 'B': bftpd++; break; #endif /* BFTPDAEMON */ case 'd': if (strcmp(optarg, "ebug") == 0) { debug++; break; } usage(); /* NOTREACHED */ break; #ifdef DIAGNOSTICS case 'D': /* * Check for desired diagnostics capabilities. */ if (!strcmp(optarg, "report")) { diagnostic |= TD_REPORT|TD_OPTIONS; } else if (!strcmp(optarg, "exercise")) { diagnostic |= TD_EXERCISE; } else if (!strcmp(optarg, "netdata")) { diagnostic |= TD_NETDATA; } else if (!strcmp(optarg, "ptydata")) { diagnostic |= TD_PTYDATA; } else if (!strcmp(optarg, "options")) { diagnostic |= TD_OPTIONS; } else { usage(); /* NOT REACHED */ } break; #endif /* DIAGNOSTICS */ #ifdef ENCRYPTION case 'e': if (strcmp(optarg, "debug") == 0) { extern int encrypt_debug_mode; encrypt_debug_mode = 1; break; } usage(); /* NOTREACHED */ break; #endif /* ENCRYPTION */ case 'h': hostinfo = 0; break; #ifdef LINEMODE case 'l': alwayslinemode = 1; break; #endif /* LINEMODE */ case 'k': #if defined(LINEMODE) && defined(KLUDGELINEMODE) lmodetype = NO_AUTOKLUDGE; #else /* ignore -k option if built without kludge linemode */ #endif /* defined(LINEMODE) && defined(KLUDGELINEMODE) */ break; case 'n': keepalive = 0; break; case 'p': altlogin = optarg; break; case 'S': #ifdef HAS_GETTOS if ((tos = parsetos(optarg, "tcp")) < 0) warnx("%s%s%s", "bad TOS argument '", optarg, "'; will try to use default TOS"); #else #define MAXTOS 255 ultmp = strtoul(optarg, &ep, 0); if (*ep || ep == optarg || ultmp > MAXTOS) warnx("%s%s%s", "bad TOS argument '", optarg, "'; will try to use default TOS"); else tos = ultmp; #endif break; case 'u': utmp_len = (size_t)atoi(optarg); if (utmp_len >= sizeof(remote_hostname)) utmp_len = sizeof(remote_hostname) - 1; break; case 'U': registerd_host_only = 1; break; #ifdef AUTHENTICATION case 'X': /* * Check for invalid authentication types */ auth_disable_name(optarg); break; #endif /* AUTHENTICATION */ case '4': family = AF_INET; break; #ifdef INET6 case '6': family = AF_INET6; break; #endif default: warnx("%c: unknown option", ch); /* FALLTHROUGH */ case '?': usage(); /* NOTREACHED */ } } argc -= optind; argv += optind; if (debug) { int s, ns, foo, error; const char *service = "telnet"; struct addrinfo hints, *res; if (argc > 1) { usage(); /* NOT REACHED */ } else if (argc == 1) service = *argv; memset(&hints, 0, sizeof(hints)); hints.ai_flags = AI_PASSIVE; hints.ai_family = family; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = 0; error = getaddrinfo(NULL, service, &hints, &res); if (error) { errx(1, "tcp/%s: %s\n", service, gai_strerror(error)); if (error == EAI_SYSTEM) errx(1, "tcp/%s: %s\n", service, strerror(errno)); usage(); } s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); if (s < 0) err(1, "socket"); (void) setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)); if (debug > 1) (void) setsockopt(s, SOL_SOCKET, SO_DEBUG, (char *)&on, sizeof(on)); if (bind(s, res->ai_addr, res->ai_addrlen) < 0) err(1, "bind"); if (listen(s, 1) < 0) err(1, "listen"); foo = res->ai_addrlen; ns = accept(s, res->ai_addr, &foo); if (ns < 0) err(1, "accept"); (void) setsockopt(ns, SOL_SOCKET, SO_DEBUG, (char *)&on, sizeof(on)); (void) dup2(ns, 0); (void) close(ns); (void) close(s); #ifdef convex } else if (argc == 1) { ; /* VOID*/ /* Just ignore the host/port name */ #endif } else if (argc > 0) { usage(); /* NOT REACHED */ } openlog("telnetd", LOG_PID | LOG_ODELAY, LOG_DAEMON); fromlen = sizeof (from); if (getpeername(0, (struct sockaddr *)&from, &fromlen) < 0) { warn("getpeername"); _exit(1); } if (keepalive && setsockopt(0, SOL_SOCKET, SO_KEEPALIVE, (char *)&on, sizeof (on)) < 0) { syslog(LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m"); } #if defined(IPPROTO_IP) && defined(IP_TOS) if (from.ss_family == AF_INET) { # if defined(HAS_GETTOS) struct tosent *tp; if (tos < 0 && (tp = gettosbyname("telnet", "tcp"))) tos = tp->t_tos; # endif if (tos < 0) tos = 020; /* Low Delay bit */ if (tos && (setsockopt(0, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(tos)) < 0) && (errno != ENOPROTOOPT) ) syslog(LOG_WARNING, "setsockopt (IP_TOS): %m"); } #endif /* defined(IPPROTO_IP) && defined(IP_TOS) */ net = 0; doit((struct sockaddr *)&from); /* NOTREACHED */ return(0); } /* end of main */
int dsstream(int sockd, const struct optstruct *opt) { int wsockd, loopw = 60, bread, port, infected = 0; struct sockaddr_in server; struct sockaddr_in peer; #ifdef HAVE_SOCKLEN_T socklen_t peer_size; #else int peer_size; #endif char buff[4096], *pt; if(write(sockd, "STREAM", 6) <= 0) { mprintf("@Can't write to the socket.\n"); return 2; } memset(buff, 0, sizeof(buff)); while(loopw) { read(sockd, buff, sizeof(buff)); if((pt = strstr(buff, "PORT"))) { pt += 5; sscanf(pt, "%d", &port); break; } loopw--; } if(!loopw) { mprintf("@Daemon not ready for stream scanning.\n"); return -1; } /* connect to clamd */ if((wsockd = socket(SOCKET_INET, SOCK_STREAM, 0)) < 0) { perror("socket()"); mprintf("@Can't create the socket.\n"); return -1; } server.sin_family = AF_INET; server.sin_port = htons(port); peer_size = sizeof(peer); if(getpeername(sockd, (struct sockaddr *) &peer, &peer_size) < 0) { perror("getpeername()"); mprintf("@Can't get socket peer name.\n"); return -1; } switch (peer.sin_family) { case AF_UNIX: server.sin_addr.s_addr = inet_addr("127.0.0.1"); break; case AF_INET: server.sin_addr.s_addr = peer.sin_addr.s_addr; break; default: mprintf("@Unexpected socket type: %d.\n", peer.sin_family); return -1; } if(connect(wsockd, (struct sockaddr *) &server, sizeof(struct sockaddr_in)) < 0) { close(wsockd); perror("connect()"); mprintf("@Can't connect to clamd [port: %d].\n", port); return -1; } while((bread = read(0, buff, sizeof(buff))) > 0) { if(write(wsockd, buff, bread) <= 0) { mprintf("@Can't write to the socket.\n"); close(wsockd); return -1; } } close(wsockd); memset(buff, 0, sizeof(buff)); while((bread = read(sockd, buff, sizeof(buff))) > 0) { mprintf("%s", buff); if(strstr(buff, "FOUND\n")) { infected++; logg("%s", buff); } else if(strstr(buff, "ERROR\n")) { logg("%s", buff); return -1; } memset(buff, 0, sizeof(buff)); } return infected; }
static void mca_btl_tcp2_endpoint_dump(mca_btl_base_endpoint_t* btl_endpoint, const char* msg) { char src[64]; char dst[64]; int sndbuf,rcvbuf,nodelay,flags; #if OPAL_ENABLE_IPV6 struct sockaddr_storage inaddr; #else struct sockaddr_in inaddr; #endif opal_socklen_t obtlen; opal_socklen_t addrlen = sizeof(inaddr); getsockname(btl_endpoint->endpoint_sd, (struct sockaddr*)&inaddr, &addrlen); #if OPAL_ENABLE_IPV6 { char *address; address = (char *) opal_net_get_hostname((struct sockaddr*) &inaddr); if (NULL != address) { sprintf(src, "%s", address); } } #else sprintf(src, "%s", inet_ntoa(inaddr.sin_addr)); #endif getpeername(btl_endpoint->endpoint_sd, (struct sockaddr*)&inaddr, &addrlen); #if OPAL_ENABLE_IPV6 { char *address; address = (char *) opal_net_get_hostname ((struct sockaddr*) &inaddr); if (NULL != address) { sprintf(dst, "%s", address); } } #else sprintf(dst, "%s", inet_ntoa(inaddr.sin_addr)); #endif if((flags = fcntl(btl_endpoint->endpoint_sd, F_GETFL, 0)) < 0) { BTL_ERROR(("fcntl(F_GETFL) failed: %s (%d)", strerror(opal_socket_errno), opal_socket_errno)); } #if defined(SO_SNDBUF) obtlen = sizeof(sndbuf); if(getsockopt(btl_endpoint->endpoint_sd, SOL_SOCKET, SO_SNDBUF, (char *)&sndbuf, &obtlen) < 0) { BTL_ERROR(("SO_SNDBUF option: %s (%d)", strerror(opal_socket_errno), opal_socket_errno)); } #else sndbuf = -1; #endif #if defined(SO_RCVBUF) obtlen = sizeof(rcvbuf); if(getsockopt(btl_endpoint->endpoint_sd, SOL_SOCKET, SO_RCVBUF, (char *)&rcvbuf, &obtlen) < 0) { BTL_ERROR(("SO_RCVBUF option: %s (%d)", strerror(opal_socket_errno), opal_socket_errno)); } #else rcvbuf = -1; #endif #if defined(TCP_NODELAY) obtlen = sizeof(nodelay); if(getsockopt(btl_endpoint->endpoint_sd, IPPROTO_TCP, TCP_NODELAY, (char *)&nodelay, &obtlen) < 0) { BTL_ERROR(("TCP_NODELAY option: %s (%d)", strerror(opal_socket_errno), opal_socket_errno)); } #else nodelay = 0; #endif BTL_VERBOSE(("%s: %s - %s nodelay %d sndbuf %d rcvbuf %d flags %08x", msg, src, dst, nodelay, sndbuf, rcvbuf, flags)); }
/* Returns file descriptor of open connection to the first available server from list passed in server table. */ int tac_connect(struct addrinfo **server, char **key, int servers) { int tries = 0; int fd, flags, retval; fd_set readfds, writefds; struct timeval tv; socklen_t len; struct sockaddr_storage addr; if(!servers) { DEBUG_TACPLUS("no TACACS+ servers defined"); return(-1); } while(tries < servers) { if((fd=socket(server[tries]->ai_family, server[tries]->ai_socktype, server[tries]->ai_protocol)) == -1) { DEBUG_TACPLUS("ocket creation error"); tries++; continue; } /* put socket in non blocking mode for timeout support */ flags = fcntl(fd, F_GETFL, 0); if(fcntl(fd, F_SETFL, flags | O_NONBLOCK)) { DEBUG_TACPLUS("cannot set socket non blocking"); tries++; continue; } retval = connect(fd, server[tries]->ai_addr, server[tries]->ai_addrlen); if((retval == -1) && (errno != EINPROGRESS)) { DEBUG_TACPLUS("connection to %s failed", tac_ntop(server[tries]->ai_addr, server[tries]->ai_addrlen)); if(fcntl(fd, F_SETFL, flags)) { DEBUG_TACPLUS("cannot restore socket flags"); } tries++; continue; } /* set fds for select */ FD_ZERO(&readfds); FD_SET(fd, &readfds); writefds = readfds; /* set timeout seconds */ tv.tv_sec = tac_timeout; tv.tv_usec = 0; /* check if socket is ready for read and write */ if(select(fd+1, &readfds, &writefds, NULL, &tv) < 1) { DEBUG_TACPLUS("connection failed with %s", tac_ntop(server[tries]->ai_addr, server[tries]->ai_addrlen)); if(fcntl(fd, F_SETFL, flags)) { DEBUG_TACPLUS("cannot restore socket flags"); } tries++; continue; } else { /* check with getpeername if we have a valid connection */ len = sizeof(addr); if(getpeername(fd, (struct sockaddr*)&addr, &len) == -1) { DEBUG_TACPLUS("connection failed with %s", tac_ntop(server[tries]->ai_addr, server[tries]->ai_addrlen)); if(fcntl(fd, F_SETFL, flags)) { DEBUG_TACPLUS("cannot restore socket flags"); } tries++; continue; } } /* connected ok */ if(fcntl(fd, F_SETFL, flags)) { DEBUG_TACPLUS("cannot restore socket flags"); } DEBUG_TACPLUS("connected to %s", tac_ntop(server[tries]->ai_addr, server[tries]->ai_addrlen)); /* set current tac_secret */ tac_secret = key[tries]; return(fd); } /* all attempts failed */ return(-1); } /* tac_connect */
/* * Initialize the server extension */ DWORD __declspec(dllexport) InitServerExtension(Remote *remote) { DWORD index; dprintf("[SERVER] Registering command handlers..."); for (index = 0; customCommands[index].method; index++) { dprintf("Registering command index %d", index); dprintf(" Command: %s", customCommands[index].method); dprintf(" Register: 0x%.8x", command_register); command_register(&customCommands[index]); } dprintf("[SERVER] Memory reset of open_captures..."); memset(open_captures, 0, sizeof(open_captures)); #ifdef _WIN32 // initialize structures for the packet sniffer sdk hMgr = NULL; hErr = 0; dprintf("[SERVER] Memory reset of include/exclude port lists..."); // wipe the include/exclude ports empty memset(sniffer_includeports, 0, sizeof(sniffer_includeports)); memset(sniffer_excludeports, 0, sizeof(sniffer_excludeports)); sniffer_includeports[0] = -1; sniffer_excludeports[0] = -1; #endif dprintf("[SERVER] Getting the peer name of our socket..."); // get the address/port of the connected control socket peername4 = NULL; peername6 = NULL; peername_len = sizeof(peername); getpeername(remote->fd, &peername, &peername_len); if(peername.sa_family == PF_INET) peername4 = (struct sockaddr_in *)&peername; dprintf("[SERVER] Getting the IPv6 peer name of our socket..."); if(peername.sa_family == PF_INET6) peername6 = (struct sockaddr_in6 *)&peername; dprintf("[SERVER] Creating a lock..."); snifferm = lock_create(); #ifdef _WIN32 return hErr; #else if(peername4 || peername6) { int port; char buf[256]; // future proof :-) memset(buf, 0, sizeof(buf)); if(peername4) { inet_ntop(AF_INET, &peername4->sin_addr, buf, sizeof(buf)-1); port = ntohs(peername4->sin_port); } else { inet_ntop(AF_INET6, &peername6->sin6_addr, buf, sizeof(buf)-1); port = ntohs(peername6->sin6_port); } asprintf(&packet_filter, "not (ip%s host %s and tcp port %d)", peername4 ? "" : "6", buf, port); dprintf("so our filter is '%s'", packet_filter); } else { dprintf("hold on to your seats. no filter applied :~("); } return ERROR_SUCCESS; #endif }
void Getpeername(int fd, struct sockaddr *sa, socklen_t *salenptr) { if (getpeername(fd, sa, salenptr) < 0) err_sys("getpeername error"); }
NOEXPORT void init_local(CLI *c) { SOCKADDR_UNION addr; socklen_t addr_len; char *accepted_address; /* check if local_rfd is a socket and get peer address */ addr_len=sizeof(SOCKADDR_UNION); c->local_rfd.is_socket=!getpeername(c->local_rfd.fd, &addr.sa, &addr_len); if(c->local_rfd.is_socket) { memcpy(&c->peer_addr.sa, &addr.sa, addr_len); c->peer_addr_len=addr_len; if(set_socket_options(c->local_rfd.fd, 1)) s_log(LOG_WARNING, "Failed to set local socket options"); } else { if(get_last_socket_error()!=S_ENOTSOCK) { sockerror("getpeerbyname (local_rfd)"); longjmp(c->err, 1); } } /* check if local_wfd is a socket and get peer address */ if(c->local_rfd.fd==c->local_wfd.fd) { c->local_wfd.is_socket=c->local_rfd.is_socket; } else { addr_len=sizeof(SOCKADDR_UNION); c->local_wfd.is_socket=!getpeername(c->local_wfd.fd, &addr.sa, &addr_len); if(c->local_wfd.is_socket) { if(!c->local_rfd.is_socket) { /* already retrieved */ memcpy(&c->peer_addr.sa, &addr.sa, addr_len); c->peer_addr_len=addr_len; } if(set_socket_options(c->local_wfd.fd, 1)) s_log(LOG_WARNING, "Failed to set local socket options"); } else { if(get_last_socket_error()!=S_ENOTSOCK) { sockerror("getpeerbyname (local_wfd)"); longjmp(c->err, 1); } } } /* neither of local descriptors is a socket */ if(!c->local_rfd.is_socket && !c->local_wfd.is_socket) { #ifndef USE_WIN32 if(c->opt->option.transparent_src) { s_log(LOG_ERR, "Transparent source needs a socket"); longjmp(c->err, 1); } #endif s_log(LOG_NOTICE, "Service [%s] accepted connection", c->opt->servname); return; } /* authenticate based on retrieved IP address of the client */ accepted_address=s_ntop(&c->peer_addr, c->peer_addr_len); #ifdef USE_LIBWRAP libwrap_auth(c, accepted_address); #endif /* USE_LIBWRAP */ auth_user(c, accepted_address); s_log(LOG_NOTICE, "Service [%s] accepted connection from %s", c->opt->servname, accepted_address); str_free(accepted_address); }
int zbx_tcp_check_security( zbx_sock_t *s, const char *ip_list, int allow_if_empty ) { #if defined(HAVE_IPV6) struct sockaddr_storage name; struct addrinfo hints, *ai = NULL; #else ZBX_SOCKADDR name; struct hostent *hp; char *sip; int i[4], j[4]; #endif socklen_t nlen; char tmp[MAX_STRING_LEN], sname[MAX_STRING_LEN], *start = NULL, *end = NULL, c = '\0'; zabbix_log( LOG_LEVEL_DEBUG, "In check_security()"); if( (1 == allow_if_empty) && ( !ip_list || !*ip_list ) ) { return SUCCEED; } nlen = sizeof(name); if( ZBX_TCP_ERROR == getpeername(s->socket, (struct sockaddr*)&name, &nlen)) { zbx_set_tcp_strerror("Connection rejected. Getpeername failed [%s]", strerror_from_system(zbx_sock_last_error())); return FAIL; } else { #if !defined(HAVE_IPV6) zbx_strlcpy(sname, inet_ntoa(name.sin_addr), sizeof(sname)); if(sscanf(sname, "%d.%d.%d.%d", &i[0], &i[1], &i[2], &i[3]) != 4) { return FAIL; } #endif /*HAVE_IPV6*/ strscpy(tmp,ip_list); for(start = tmp; start[0] != '\0';) { end = strchr(start, ','); if(end != NULL) { c = end[0]; end[0] = '\0'; } /* Allow IP addresses or DNS names for authorization */ #if defined(HAVE_IPV6) memset(&hints, 0, sizeof(hints)); hints.ai_family = PF_UNSPEC; if(0 == getaddrinfo(start, NULL, &hints, &ai)) { if(ai->ai_family == name.ss_family) { switch(ai->ai_family) { case AF_INET : if(((struct sockaddr_in*)&name)->sin_addr.s_addr == ((struct sockaddr_in*)ai->ai_addr)->sin_addr.s_addr) { freeaddrinfo(ai); return SUCCEED; } case AF_INET6 : if(0 == memcmp(((struct sockaddr_in6*)&name)->sin6_addr.s6_addr, ((struct sockaddr_in6*)ai->ai_addr)->sin6_addr.s6_addr, sizeof(struct in6_addr))) { freeaddrinfo(ai); return SUCCEED; } } } freeaddrinfo(ai); } #else if( 0 != (hp = zbx_gethost(start))) { sip = inet_ntoa(*((struct in_addr *)hp->h_addr)); if(sscanf(sip, "%d.%d.%d.%d", &j[0], &j[1], &j[2], &j[3]) == 4) { if(i[0] == j[0] && i[1] == j[1] && i[2] == j[2] && i[3] == j[3]) { return SUCCEED; } } } #endif /*HAVE_IPV6*/ if(end != NULL) { end[0] = c; start = end + 1; } else { break; } } if(end != NULL) { end[0] = c; } } #if defined(HAVE_IPV6) if(0 == getnameinfo((struct sockaddr*)&name, sizeof(name), sname, sizeof(sname), NULL, 0, NI_NUMERICHOST)) { zbx_set_tcp_strerror("Connection from [%s] rejected. Allowed server is [%s] ",sname, ip_list); } else { zbx_set_tcp_strerror("Connection rejected. Allowed server is [%s] ", ip_list); } #else zbx_set_tcp_strerror("Connection from [%s] rejected. Allowed server is [%s] ",sname, ip_list); #endif /*HAVE_IPV6*/ return FAIL; }
/* This function does the actual connecting */ int mongo_connection_connect(char *host, int port, int timeout, char **error_message) { struct sockaddr* sa; struct sockaddr_in si; socklen_t sn; int family; struct timeval tval; int connected; int status; int tmp_socket; #ifdef WIN32 WORD version; WSADATA wsaData; int size, error; u_long no = 0; const char yes = 1; #else struct sockaddr_un su; uint size; int yes = 1; #endif *error_message = NULL; #ifdef WIN32 family = AF_INET; sa = (struct sockaddr*)(&si); sn = sizeof(si); version = MAKEWORD(2,2); error = WSAStartup(version, &wsaData); if (error != 0) { return -1; } /* create socket */ tmp_socket = socket(family, SOCK_STREAM, 0); if (tmp_socket == INVALID_SOCKET) { *error_message = strdup(strerror(errno)); return -1; } #else /* domain socket */ if (port == 0) { family = AF_UNIX; sa = (struct sockaddr*)(&su); sn = sizeof(su); } else { family = AF_INET; sa = (struct sockaddr*)(&si); sn = sizeof(si); } /* create socket */ if ((tmp_socket = socket(family, SOCK_STREAM, 0)) == -1) { *error_message = strdup(strerror(errno)); return -1; } #endif /* TODO: Move this to within the loop & use real timeout setting */ /* connection timeout: set in ms (current default 1000 secs) */ tval.tv_sec = timeout <= 0 ? 1000 : timeout / 1000; tval.tv_usec = timeout <= 0 ? 0 : (timeout % 1000) * 1000; /* get addresses */ if (mongo_util_connect__sockaddr(sa, family, host, port, error_message) == 0) { goto error; } setsockopt(tmp_socket, SOL_SOCKET, SO_KEEPALIVE, &yes, INT_32); setsockopt(tmp_socket, IPPROTO_TCP, TCP_NODELAY, &yes, INT_32); #ifdef WIN32 ioctlsocket(tmp_socket, FIONBIO, (u_long*)&yes); #else fcntl(tmp_socket, F_SETFL, FLAGS|O_NONBLOCK); #endif /* connect */ status = connect(tmp_socket, sa, sn); if (status < 0) { #ifdef WIN32 errno = WSAGetLastError(); if (errno != WSAEINPROGRESS && errno != WSAEWOULDBLOCK) { #else if (errno != EINPROGRESS) { #endif *error_message = strdup(strerror(errno)); goto error; } while (1) { fd_set rset, wset, eset; FD_ZERO(&rset); FD_SET(tmp_socket, &rset); FD_ZERO(&wset); FD_SET(tmp_socket, &wset); FD_ZERO(&eset); FD_SET(tmp_socket, &eset); if (select(tmp_socket+1, &rset, &wset, &eset, &tval) == 0) { *error_message = malloc(256); snprintf(*error_message, 256, "Timed out after %d ms", timeout); goto error; } /* if our descriptor has an error */ if (FD_ISSET(tmp_socket, &eset)) { *error_message = strdup(strerror(errno)); goto error; } /* if our descriptor is ready break out */ if (FD_ISSET(tmp_socket, &wset) || FD_ISSET(tmp_socket, &rset)) { break; } } size = sn; connected = getpeername(tmp_socket, sa, &size); if (connected == -1) { *error_message = strdup(strerror(errno)); goto error; } } /* reset flags */ #ifdef WIN32 ioctlsocket(tmp_socket, FIONBIO, &no); #else fcntl(tmp_socket, F_SETFL, FLAGS); #endif return tmp_socket; error: #ifdef WIN32 shutdown((tmp_socket), 2); closesocket(tmp_socket); WSACleanup(); #else shutdown((tmp_socket), 2); close(tmp_socket); #endif return -1; } mongo_connection *mongo_connection_create(mongo_con_manager *manager, mongo_server_def *server_def, char **error_message) { mongo_connection *tmp; /* Init struct */ tmp = malloc(sizeof(mongo_connection)); memset(tmp, 0, sizeof(mongo_connection)); tmp->last_reqid = rand(); tmp->connection_type = MONGO_NODE_STANDALONE; /* Connect */ mongo_manager_log(manager, MLOG_CON, MLOG_INFO, "connection_create: creating new connection for %s:%d", server_def->host, server_def->port); tmp->socket = mongo_connection_connect(server_def->host, server_def->port, 1000, error_message); if (tmp->socket == -1) { mongo_manager_log(manager, MLOG_CON, MLOG_WARN, "connection_create: error while creating connection for %s:%d: %s", server_def->host, server_def->port, *error_message); free(tmp); return NULL; } /* We call get_server_flags to the maxBsonObjectSize data */ mongo_connection_get_server_flags(manager, tmp, (char**) &error_message); return tmp; }
/* * Perform a test session. */ static void DoSession( int CtrlSock ) { struct sockaddr_in LocSa; struct stat statbuf; int SaLen, Vmajor, Vminor; char str[256], *line, *p; /* * Get the source address from the control socket. */ SaLen = sizeof LocSa; if( getpeername( CtrlSock, (struct sockaddr *)(&LocSa), &SaLen ) != 0 ) { syslog( LOG_ERR, "Can't get source address from control socket (%m)" ); close( CtrlSock ); exit( 1 ); } syslog( LOG_INFO, "Connection from %s:%d", inet_ntoa( LocSa.sin_addr ), ntohs( LocSa.sin_port ) ); SourceAddress = LocSa.sin_addr; /* * Check if DENYFILE exists and if so, refuse connection */ if (stat(DENYFILE, &statbuf) == 0) { syslog( LOG_INFO, "Connection from %s:%d refused: DENYFILE (%s) exists", inet_ntoa( LocSa.sin_addr ), ntohs( LocSa.sin_port ), DENYFILE); Reply(CtrlSock, 410, "Service temporarily disabled. Please try later"); usleep( 200000 ); close( CtrlSock ); exit( 1 ); } /* * Get the HELO/INFO request from a client */ if ((line = ReadLineTimeout(CtrlSock, 10)) == NULL) { close( CtrlSock ); exit( 1 ); } p = line; if (strncmp(p, "HELO ", 5) != 0) { if (strncmp(p, "INFO", 4) != 0) { Reply(CtrlSock, 510, "Syntax error"); close( CtrlSock ); exit( 1 ); } else { /* Send INFO */ char str[100]; int i = 0; while (strlen(Info[i])) { sprintf(str, "250-%s\r\n", Info[i]); if (write(CtrlSock, str, strlen(str)) != strlen(str)) { syslog( LOG_ERR, "Error writing to socket (%m)"); close( CtrlSock ); exit( 1 ); } i++; } Reply(CtrlSock, 250, ""); } } else { char tBuf[50]; memset(tBuf, 0, 50); p += 5; if (CopyTagField(tBuf, 49, p, "vmajor")) Vmajor = atoi(tBuf); else Vmajor = 0; if (CopyTagField(tBuf, 49, p, "vminor")) Vminor = atoi(tBuf); else Vminor = 0; if (Vmajor < MajorVersion) { sprintf(str, "You need to upgrade, Go to %s", UPGRADE_URL); Reply(CtrlSock, 501, str); usleep( 200000 ); close( CtrlSock ); exit( 1 ); } SendServerList( CtrlSock ); } usleep( 200000 ); close( CtrlSock ); exit( 0 ); }
/* * cmyth_conn_connect_path(char* path, cmyth_conn_t control, * unsigned buflen, int tcp_rcvbuf) * * Scope: PUBLIC * * Description: * * Create a file structure containing a data connection for use * transfering a file within the MythTV protocol. Return a pointer to * the newly created file structure. The connection in the file * structure is returned held as is the file structure itself. The * connection will be released when the file structure is released. * The file structure can be released using ref_release(). * * Return Value: * * Success: Non-NULL cmyth_file_t (this is a pointer type) * * Failure: NULL cmyth_file_t */ cmyth_file_t cmyth_conn_connect_path(char* path, cmyth_conn_t control, unsigned buflen, int tcp_rcvbuf, char* storage_group) { cmyth_conn_t conn = NULL; char *announcement = NULL; char reply[16]; char host[256]; int err = 0; int count = 0; int r, port; int ann_size = sizeof("ANN FileTransfer 0[]:[][]:[]"); struct sockaddr_in addr; socklen_t addr_size = sizeof(addr); cmyth_file_t ret = NULL; if (getpeername(control->conn_fd, (struct sockaddr*)&addr, &addr_size)<0) { cmyth_dbg(CMYTH_DBG_ERROR, "%s: getpeername() failed\n", __FUNCTION__); goto shut; } inet_ntop(addr.sin_family, &addr.sin_addr, host, sizeof(host)); port = ntohs(addr.sin_port); ret = cmyth_file_create(control); if (!ret) { cmyth_dbg(CMYTH_DBG_ERROR, "%s: cmyth_file_create() failed\n", __FUNCTION__); goto shut; } cmyth_dbg(CMYTH_DBG_PROTO, "%s: connecting data connection\n", __FUNCTION__); conn = cmyth_connect(host, port, buflen, tcp_rcvbuf); cmyth_dbg(CMYTH_DBG_PROTO, "%s: done connecting data connection, conn = %p\n", __FUNCTION__, conn); if (!conn) { cmyth_dbg(CMYTH_DBG_ERROR, "%s: cmyth_connect(%s, %d, %d) failed\n", __FUNCTION__, host, port, buflen); goto shut; } /* * Explicitly set the conn version to the control version as cmyth_connect() doesn't and some of * the cmyth_rcv_* functions expect it to be the same as the protocol version used by mythbackend. */ conn->conn_version = control->conn_version; ann_size += strlen(path) + strlen(my_hostname) + strlen(storage_group) + 6; announcement = malloc(ann_size); if (!announcement) { cmyth_dbg(CMYTH_DBG_ERROR, "%s: malloc(%d) failed for announcement\n", __FUNCTION__, ann_size); goto shut; } if (control->conn_version >= 44) { /*TSP: from version 44 according to the source code*/ if (strlen(storage_group) > 1) { sprintf(announcement, "ANN FileTransfer %s 0 0 0[]:[]%s[]:[]%s", my_hostname, path, storage_group); } else { sprintf(announcement, "ANN FileTransfer %s 0[]:[]%s[]:[]", // write = false my_hostname, path); } } else { sprintf(announcement, "ANN FileTransfer %s[]:[]%s", my_hostname, path); } if (cmyth_send_message(conn, announcement) < 0) { cmyth_dbg(CMYTH_DBG_ERROR, "%s: cmyth_send_message('%s') failed\n", __FUNCTION__, announcement); goto shut; } ret->file_data = ref_hold(conn); count = cmyth_rcv_length(conn); if (count < 0) { cmyth_dbg(CMYTH_DBG_ERROR, "%s: cmyth_rcv_length() failed (%d)\n", __FUNCTION__, count); goto shut; } reply[sizeof(reply) - 1] = '\0'; r = cmyth_rcv_string(conn, &err, reply, sizeof(reply) - 1, count); if (err != 0) { cmyth_dbg(CMYTH_DBG_ERROR, "%s: cmyth_rcv_string() failed (%d)\n", __FUNCTION__, err); goto shut; } if (strcmp(reply, "OK") != 0) { cmyth_dbg(CMYTH_DBG_ERROR, "%s: reply ('%s') is not 'OK'\n", __FUNCTION__, reply); goto shut; } count -= r; r = cmyth_rcv_long(conn, &err, &ret->file_id, count); if (err) { cmyth_dbg(CMYTH_DBG_ERROR, "%s: (id) cmyth_rcv_long() failed (%d)\n", __FUNCTION__, err); goto shut; } count -= r; r = cmyth_rcv_uint64(conn, &err, &ret->file_length, count); if (err) { cmyth_dbg(CMYTH_DBG_ERROR, "%s: (length) cmyth_rcv_uint64() failed (%d)\n", __FUNCTION__, err); goto shut; } count -= r; free(announcement); ref_release(conn); return ret; shut: if (announcement) { free(announcement); } ref_release(ret); ref_release(conn); return NULL; }
//////////////////////////////////////////////////////////// /// Connect to another computer on a specified port //////////////////////////////////////////////////////////// Socket::Status SocketTCP::Connect(unsigned short Port, const IPAddress& HostAddress, float Timeout) { // Make sure our socket is valid if (!IsValid()) Create(); // Build the host address sockaddr_in SockAddr; memset(SockAddr.sin_zero, 0, sizeof(SockAddr.sin_zero)); SockAddr.sin_addr.s_addr = inet_addr(HostAddress.ToString().c_str()); SockAddr.sin_family = AF_INET; SockAddr.sin_port = htons(Port); if (Timeout <= 0) { // ----- We're not using a timeout : just try to connect ----- if (connect(mySocket, reinterpret_cast<sockaddr*>(&SockAddr), sizeof(SockAddr)) == -1) { // Failed to connect return SocketHelper::GetErrorStatus(); } // Connection succeeded return Socket::Done; } else { // ----- We're using a timeout : we'll need a few tricks to make it work ----- // Save the previous blocking state bool IsBlocking = myIsBlocking; // Switch to non-blocking to enable our connection timeout if (IsBlocking) SetBlocking(false); // Try to connect to host if (connect(mySocket, reinterpret_cast<sockaddr*>(&SockAddr), sizeof(SockAddr)) >= 0) { // We got instantly connected! (it may no happen a lot...) return Socket::Done; } // Get the error status Socket::Status Status = SocketHelper::GetErrorStatus(); // If we were in non-blocking mode, return immediatly if (!IsBlocking) return Status; // Otherwise, wait until something happens to our socket (success, timeout or error) if (Status == Socket::NotReady) { // Setup the selector fd_set Selector; FD_ZERO(&Selector); FD_SET(mySocket, &Selector); // Setup the timeout timeval Time; Time.tv_sec = static_cast<long>(Timeout); Time.tv_usec = (static_cast<long>(Timeout * 1000) % 1000) * 1000; // Wait for something to write on our socket (which means that the connection request has returned) if (select(static_cast<int>(mySocket + 1), NULL, &Selector, NULL, &Time) > 0) { // At this point the connection may have been either accepted or refused. // To know whether it's a success or a failure, we try to retrieve the name of the connected peer SocketHelper::LengthType Size = sizeof(SockAddr); if (getpeername(mySocket, reinterpret_cast<sockaddr*>(&SockAddr), &Size) != -1) { // Connection accepted Status = Socket::Done; } else { // Connection failed Status = SocketHelper::GetErrorStatus(); } } else { // Failed to connect before timeout is over Status = SocketHelper::GetErrorStatus(); } } // Switch back to blocking mode SetBlocking(true); return Status; } }
static int do_connect(char *host, int port) { int sock; struct sockaddr_in addr, check_connect; fd_set rset, wset; struct timeval timeout; // start unconnected int connected = 0; #ifdef WIN32 WORD version; WSADATA wsaData; int size, error; u_long no = 0; const char yes = 1; version = MAKEWORD(2,2); error = WSAStartup(version, &wsaData); if (error != 0) { return 0; } // create socket sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (sock == INVALID_SOCKET) { return 0; } #else uint size; int yes = 1; // create socket if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) { croak("couldn't create socket: %s\n", strerror(errno)); return -1; } #endif // timeout timeout.tv_sec = 20; timeout.tv_usec = 0; // get addresses if (!mongo_link_sockaddr(&addr, host, port)) { return -1; } setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &yes, INT_32); setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &yes, INT_32); #ifdef WIN32 ioctlsocket(sock, FIONBIO, (u_long*)&yes); #else fcntl(sock, F_SETFL, O_NONBLOCK); #endif FD_ZERO(&rset); FD_SET(sock, &rset); FD_ZERO(&wset); FD_SET(sock, &wset); // connect if (connect(sock, (struct sockaddr*)&addr, sizeof(addr)) == -1) { #ifdef WIN32 errno = WSAGetLastError(); if (errno != WSAEINPROGRESS && errno != WSAEWOULDBLOCK) #else if (errno != EINPROGRESS) #endif { return -1; } if (!select(sock+1, &rset, &wset, 0, &timeout)) { return -1; } size = sizeof(check_connect); connected = getpeername(sock, (struct sockaddr*)&addr, &size); if (connected == -1) { return -1; } } // reset flags #ifdef WIN32 ioctlsocket(sock, FIONBIO, &no); #else fcntl(sock, F_SETFL, 0); #endif return sock; }
static void ProcessNewPMConnection ( int * nfds, fd_set * rinit, struct config * config_info, IceListenObj ** listen_objects, int listen_fd) { IceConn new_ice_conn; IceAcceptStatus accept_status; int temp_sock_fd; IceListenObj * temp_obj; struct timeval time_val; struct timezone time_zone; struct sockaddr_in temp_sockaddr_in; struct sockaddr_in server_sockaddr_in; int retval; int addrlen = sizeof(temp_sockaddr_in); int rule_number; int pm_idx; /* * Only continue if there is room for another PM connection. */ for (pm_idx = 0; pm_idx < config_info->num_pm_conns; pm_idx++) { if (!pm_conn_array[pm_idx]) break; } if (pm_idx >= config_info->num_pm_conns) { (void) fprintf (stderr, "Maximum number of PM connections has been reached (%d)\n", config_info->num_pm_conns); /* * Must accept and then close this connection or the PM will * continue to poll. */ temp_obj = *listen_objects; new_ice_conn = IceAcceptConnection(temp_obj[listen_fd], &accept_status); if (new_ice_conn) IceCloseConnection(new_ice_conn); return; } /* * accept the connection if you can, use pm_listen_array * index to index into ICE listen_object list (this is because the * listen_objects list must correspond to the pm_listen_array) */ temp_obj = *listen_objects; new_ice_conn = IceAcceptConnection(temp_obj[listen_fd], &accept_status); if (!new_ice_conn) { static int been_here; /* * ICE initialization (bug?) makes this happen the * first time readables is hit. */ if (!been_here) been_here++; else (void) fprintf(stderr, "IceAcceptConnection failed (%d)\n", accept_status); return; } /* * extract the fd from this new connection; remember, the fd of * the listen socket is *not* the fd of the actual connection! */ temp_sock_fd = IceConnectionNumber(new_ice_conn); /* * before we get any further, do a config check on the new ICE * connection; start by using getpeername() to get endpoint info */ retval = getpeername(temp_sock_fd, (struct sockaddr*)&temp_sockaddr_in, (void *)&addrlen); if (retval) { IceCloseConnection(new_ice_conn); (void) fprintf(stderr, "getpeername call failed\n"); return; } assert(temp_sockaddr_in.sin_family == AF_INET); /* * Do a configuration check. NOTE: we're not doing anything * with the server_sockaddr_in argument */ if ((doConfigCheck(&temp_sockaddr_in, &server_sockaddr_in, config_info, PMGR, &rule_number)) == FAILURE) { /* * close the PM connection * */ (void) fprintf(stderr, "PM failed config check\n"); IceCloseConnection(new_ice_conn); return; } /* * you've started the connection process; allocate a buffer * for this connection, then continue processing other fd's without * blocking while waiting to read the coming PM data; [NOTE: * we use the fd of the connection socket as index into the * pm_conn_array; this saves us much troublesome linked-list * management!] */ if ((pm_conn_array[pm_idx] = malloc(sizeof(struct pm_conn_buf))) == NULL) { (void) fprintf (stderr, "malloc - PM connection object\n"); return; } /* * save the ICEconn struct for future status checks; also * the fd (although you could extract it from the ICEconn * each time you need it, but that's a pain) */ pm_conn_array[pm_idx]->fd = temp_sock_fd; pm_conn_array[pm_idx]->ice_conn = new_ice_conn; /* * Set the readables select() to listen for a readable on this * fd; remember, we're not interested in pm writables, since * all the negotiation is handled inside this routine; adjust * the nfds (must do that every time we get a new socket to * select() on), and then continue processing current selections */ FD_SET(temp_sock_fd, rinit); *nfds = max(*nfds, temp_sock_fd + 1); /* * this is where we initialize the current time and timeout on this * pm_connection object */ (void) gettimeofday(&time_val, &time_zone); pm_conn_array[pm_idx]->creation_time = time_val.tv_sec; pm_conn_array[pm_idx]->time_to_close = config_info->pm_data_timeout; }
//************************************************************************************ // // Socket Transmit to Socket // //************************************************************************************ void transmitdata(LPVOID data) { SOCKET fd1, fd2; transocket *sock; struct timeval timeset; fd_set readfd,writefd; int result,i=0; char read_in1[MAXSIZE],send_out1[MAXSIZE]; char read_in2[MAXSIZE],send_out2[MAXSIZE]; int read1=0,totalread1=0,send1=0; int read2=0,totalread2=0,send2=0; int sendcount1,sendcount2; int maxfd; struct sockaddr_in client1,client2; int structsize1,structsize2; char host1[20],host2[20]; int port1=0,port2=0; char tmpbuf[100]; sock = (transocket *)data; fd1 = sock->fd1; fd2 = sock->fd2; memset(host1,0,20); memset(host2,0,20); memset(tmpbuf,0,100); structsize1=sizeof(struct sockaddr); structsize2=sizeof(struct sockaddr); if(getpeername(fd1,(struct sockaddr *)&client1,&structsize1)<0) { strcpy(host1, "fd1"); } else { // printf("[+]got, ip:%s, port:%d\r\n",inet_ntoa(client1.sin_addr),ntohs(client1.sin_port)); strcpy(host1, inet_ntoa(client1.sin_addr)); port1=ntohs(client1.sin_port); } if(getpeername(fd2,(struct sockaddr *)&client2,&structsize2)<0) { strcpy(host2,"fd2"); } else { // printf("[+]got, ip:%s, port:%d\r\n",inet_ntoa(client2.sin_addr),ntohs(client2.sin_port)); strcpy(host2, inet_ntoa(client2.sin_addr)); port2=ntohs(client2.sin_port); } printf("[+] Start Transmit (%s:%d <-> %s:%d) ......\r\n\n", host1, port1, host2, port2); maxfd=max(fd1,fd2)+1; memset(read_in1,0,MAXSIZE); memset(read_in2,0,MAXSIZE); memset(send_out1,0,MAXSIZE); memset(send_out2,0,MAXSIZE); timeset.tv_sec=TIMEOUT; timeset.tv_usec=0; while(1) { FD_ZERO(&readfd); FD_ZERO(&writefd); FD_SET((UINT)fd1, &readfd); FD_SET((UINT)fd1, &writefd); FD_SET((UINT)fd2, &writefd); FD_SET((UINT)fd2, &readfd); result=select(maxfd,&readfd,&writefd,NULL,×et); if((result<0) && (errno!=EINTR)) { printf("[-] Select error.\r\n"); break; } else if(result==0) { printf("[-] Socket time out.\r\n"); break; } if(FD_ISSET(fd1, &readfd)) { /* must < MAXSIZE-totalread1, otherwise send_out1 will flow */ if(totalread1<MAXSIZE) { read1=recv(fd1, read_in1, MAXSIZE-totalread1, 0); if((read1==SOCKET_ERROR) || (read1==0)) { printf("[-] Read fd1 data error,maybe close?\r\n"); break; } memcpy(send_out1+totalread1,read_in1,read1); sprintf(tmpbuf,"\r\nRecv %5d bytes from %s:%d\r\n", read1, host1, port1); printf(" Recv %5d bytes %16s:%d\r\n", read1, host1, port1); makelog(tmpbuf,strlen(tmpbuf)); makelog(read_in1,read1); totalread1+=read1; memset(read_in1,0,MAXSIZE); } } if(FD_ISSET(fd2, &writefd)) { int err=0; sendcount1=0; while(totalread1>0) { send1=send(fd2, send_out1+sendcount1, totalread1, 0); if(send1==0)break; if((send1<0) && (errno!=EINTR)) { printf("[-] Send to fd2 unknow error.\r\n"); err=1; break; } if((send1<0) && (errno==ENOSPC)) break; sendcount1+=send1; totalread1-=send1; printf(" Send %5d bytes %16s:%d\r\n", send1, host2, port2); } if(err==1) break; if((totalread1>0) && (sendcount1>0)) { /* move not sended data to start addr */ memcpy(send_out1,send_out1+sendcount1,totalread1); memset(send_out1+totalread1,0,MAXSIZE-totalread1); } else memset(send_out1,0,MAXSIZE); } if(FD_ISSET(fd2, &readfd)) { if(totalread2<MAXSIZE) { read2=recv(fd2,read_in2,MAXSIZE-totalread2, 0); if(read2==0)break; if((read2<0) && (errno!=EINTR)) { printf("[-] Read fd2 data error,maybe close?\r\n\r\n"); break; } memcpy(send_out2+totalread2,read_in2,read2); sprintf(tmpbuf, "\r\nRecv %5d bytes from %s:%d\r\n", read2, host2, port2); printf(" Recv %5d bytes %16s:%d\r\n", read2, host2, port2); makelog(tmpbuf,strlen(tmpbuf)); makelog(read_in2,read2); totalread2+=read2; memset(read_in2,0,MAXSIZE); } } if(FD_ISSET(fd1, &writefd)) { int err2=0; sendcount2=0; while(totalread2>0) { send2=send(fd1, send_out2+sendcount2, totalread2, 0); if(send2==0)break; if((send2<0) && (errno!=EINTR)) { printf("[-] Send to fd1 unknow error.\r\n"); err2=1; break; } if((send2<0) && (errno==ENOSPC)) break; sendcount2+=send2; totalread2-=send2; printf(" Send %5d bytes %16s:%d\r\n", send2, host1, port1); } if(err2==1) break; if((totalread2>0) && (sendcount2 > 0)) { /* move not sended data to start addr */ memcpy(send_out2, send_out2+sendcount2, totalread2); memset(send_out2+totalread2, 0, MAXSIZE-totalread2); } else memset(send_out2,0,MAXSIZE); } Sleep(5); } closesocket(fd1); closesocket(fd2); // if(method == 3) // connectnum --; printf("\r\n[+] OK! I Closed The Two Socket.\r\n"); }
/* * Open control connection to SAM's rft server on remote host. */ static SamrftImpl_t * connectToServer( char *host, int attempts) { static boolean_t infinite = B_TRUE; int af; int errcode; char errbuf[SPM_ERRSTR_MAX]; int cntl_fd; SamrftImpl_t *rft; int tos; rft = initRftImpl(); while (infinite) { cntl_fd = spm_connect_to_service(SAMRFT_SPM_SERVICE_NAME, host, NULL, &errcode, errbuf); if (cntl_fd >= 0) { break; } /* * Connect failed. */ Trace(TR_RFT, "Connection to host '%s' failed: %d: %s", host, errcode, errbuf); attempts--; if (attempts < 0) { break; } /* * Wait and try again. */ sleep(2); } if (cntl_fd < 0) { SamFree(rft); rft = NULL; } else { char *hostname; struct sockaddr_in6 mysock; struct sockaddr_in6 *mysock6; struct sockaddr_in *mysock4; struct sockaddr_in6 peername; struct sockaddr *perp; int peername_len; int mysock_len; int level; mysock6 = &mysock; mysock4 = (struct sockaddr_in *)&mysock; perp = (struct sockaddr *)&peername; peername_len = sizeof (struct sockaddr_in6); if (getpeername(cntl_fd, perp, &peername_len) < 0) { Trace(TR_ERR, "getpeername(%d) failed %d", cntl_fd, errno); } level = (peername_len == sizeof (struct sockaddr_in6)) ? IPPROTO_IPV6 : IPPROTO_IP; tos = IPTOS_LOWDELAY; if (setsockopt(cntl_fd, level, IP_TOS, (char *)&tos, sizeof (int)) < 0) { Trace(TR_ERR, "setsockopt(IPTOS_LOWDELAY) failed %d", errno); } rft->cin = fdopen(cntl_fd, "r"); rft->cout = fdopen(cntl_fd, "w"); rft->remotehost = B_TRUE; /* * Initialize the client hostname. Using cntl_fd, find the * address for the control socket. We want to use the same * interface for the data connection. */ mysock_len = sizeof (mysock); memset(&mysock, 0, mysock_len); (void) getsockname(cntl_fd, (struct sockaddr *)&mysock, (int *)&mysock_len); /* * Save the interface address used to reach the server. * This needs to be used when setting up the data port. * Find the associated hostname for this address. */ af = mysock.sin6_family; if (af == AF_INET6) { memcpy(&rft->caddr.cad6, mysock6, sizeof (struct sockaddr_in6)); rft->flags |= SAMRFT_IPV6; hostname = SamrftGetHostByAddr( (char *)&rft->Si_addr6.s6_addr[0], af); } else { memcpy(&rft->caddr.cad, mysock4, sizeof (struct sockaddr_in)); hostname = SamrftGetHostByAddr( (char *)&rft->Si_addr.s_addr, af); } if (hostname) { SamMalloc(rft->hostname, (MAXHOSTNAMELEN+1)); strncpy(rft->hostname, hostname, MAXHOSTNAMELEN); free(hostname); } else { /* * Can't find hostname for this address. */ Trace(TR_ERR, "SamrftGetHostByAddr() for client failed %d", errno); SamFree(rft); rft = NULL; return (rft); } initCmdPort(rft); } return (rft); }
static void print_fd (int fd, int depth) { #ifdef DBUS_UNIX int ret; struct stat statbuf = {0,}; union { struct sockaddr sa; struct sockaddr_storage storage; struct sockaddr_un un; struct sockaddr_in ipv4; struct sockaddr_in6 ipv6; } addr, peer; char hostip[INET6_ADDRSTRLEN]; int addrlen = sizeof (addr); int peerlen = sizeof (peer); int has_peer; #endif /* Don't print the fd number: it is different in every process and since * dbus-monitor closes the fd after reading it, the same number would be * printed again and again. */ printf ("file descriptor\n"); if (fd == -1) return; #ifdef DBUS_UNIX ret = fstat (fd, &statbuf); if (ret == -1) return; indent (depth+1); printf ("inode: %d\n", (int) statbuf.st_ino); indent (depth+1); printf ("type: "); if (S_ISREG(statbuf.st_mode)) printf ("file\n"); if (S_ISDIR(statbuf.st_mode)) printf ("directory\n"); if (S_ISCHR(statbuf.st_mode)) printf ("char\n"); if (S_ISBLK(statbuf.st_mode)) printf ("block\n"); if (S_ISFIFO(statbuf.st_mode)) printf ("fifo\n"); if (S_ISLNK(statbuf.st_mode)) printf ("link\n"); if (S_ISSOCK(statbuf.st_mode)) printf ("socket\n"); /* If it's not a socket, getsockname will just return -1 with errno * ENOTSOCK. */ memset (&addr, 0, sizeof (addr)); memset (&peer, 0, sizeof (peer)); if (getsockname(fd, &addr.sa, &addrlen)) return; has_peer = !getpeername(fd, &peer.sa, &peerlen); indent (depth+1); printf ("address family: "); switch (addr.sa.sa_family) { case AF_UNIX: printf("unix\n"); if (addr.un.sun_path[0] == '\0') { /* Abstract socket might not be zero-terminated and length is * variable. Who designed this interface? * Write the name in the same way as /proc/net/unix * See manual page unix(7) */ indent (depth+1); printf ("name @%.*s\n", (int) (addrlen - sizeof (sa_family_t) - 1), &(addr.un.sun_path[1])); if (has_peer) { indent (depth+1); printf ("peer @%.*s\n", (int) (addrlen - sizeof (sa_family_t) - 1), &(addr.un.sun_path[1])); } } else { indent (depth+1); printf ("name %s\n", addr.un.sun_path); if (has_peer) { indent (depth+1); printf ("peer %s\n", peer.un.sun_path); } } break; case AF_INET: printf ("inet\n"); if (inet_ntop (AF_INET, &addr.ipv4.sin_addr, hostip, sizeof (hostip))) { indent (depth+1); printf ("name %s port %u\n", hostip, ntohs (addr.ipv4.sin_port)); } if (has_peer && inet_ntop (AF_INET, &peer.ipv4.sin_addr, hostip, sizeof (hostip))) { indent (depth+1); printf ("peer %s port %u\n", hostip, ntohs (peer.ipv4.sin_port)); } break; #ifdef AF_INET6 case AF_INET6: printf ("inet6\n"); if (inet_ntop (AF_INET6, &addr.ipv6.sin6_addr, hostip, sizeof (hostip))) { indent (depth+1); printf ("name %s port %u\n", hostip, ntohs (addr.ipv6.sin6_port)); } if (has_peer && inet_ntop (AF_INET6, &peer.ipv6.sin6_addr, hostip, sizeof (hostip))) { indent (depth+1); printf ("peer %s port %u\n", hostip, ntohs (peer.ipv6.sin6_port)); } break; #endif #ifdef AF_BLUETOOTH case AF_BLUETOOTH: printf ("bluetooth\n"); break; #endif default: printf ("unknown (%d)\n", addr.sa.sa_family); break; } #endif }
int VMPI_getpeername(int socket, struct sockaddr *address, socklen_t *address_len) { return getpeername( socket, address, address_len ); }
/* handle a file descriptor event */ int httpd_handle_event(fd_set *rset, fd_set *wset, fd_sets_t *fds) { struct REQUEST *req, *prev, *tmp; int length; int opt = 0; now = time(NULL); /* new connection ? */ if ((rset != NULL) && FD_ISSET(slisten, rset)) { req = malloc(sizeof(struct REQUEST)); if (NULL == req) { /* oom: let the request sit in the listen queue */ #ifdef DEBUG fprintf(stderr,"oom\n"); #endif } else { memset(req,0,sizeof(struct REQUEST)); if ((req->fd = accept(slisten,NULL,&opt)) == -1) { if (EAGAIN != errno) { log_error_func(1, LOG_WARNING,"accept",NULL); } free(req); } else { fcntl(req->fd,F_SETFL,O_NONBLOCK); req->bfd = -1; req->state = STATE_READ_HEADER; req->ping = now; req->lifespan = -1; req->next = conns; conns = req; curr_conn++; #ifdef DEBUG fprintf(stderr,"%03d/%d: new request (%d)\n",req->fd,req->state,curr_conn); #endif #ifdef USE_SSL if (with_ssl) { open_ssl_session(req); } #endif length = sizeof(req->peer); if (getpeername(req->fd,(struct sockaddr*)&(req->peer),&length) == -1) { log_error_func(1, LOG_WARNING,"getpeername",NULL); req->state = STATE_CLOSE; } getnameinfo((struct sockaddr*)&req->peer,length, req->peerhost,64,req->peerserv,8, NI_NUMERICHOST | NI_NUMERICSERV); #ifdef DEBUG fprintf(stderr,"%03d/%d: connect from (%s)\n", req->fd,req->state,req->peerhost); #endif /* host auth callback */ if (access_check_func != NULL) { if (access_check_func(req->peerhost, NULL) < 0) { /* read request */ read_header(req,0); req->ping = now; /* reply with access denied and close connection */ mkerror(req,403,0); write_request(req); req->state = STATE_CLOSE; } } FD_SET(req->fd, &fds->rset); if (req->fd > fds->max) { fds->max = req->fd; } } } } /* check active connections */ for (req = conns, prev = NULL; req != NULL;) { /* I/O */ if ((rset != NULL) && FD_ISSET(req->fd, rset)) { if (req->state == STATE_KEEPALIVE) { req->state = STATE_READ_HEADER; } if (req->state == STATE_READ_HEADER) { while (read_header(req,0) > 0); } if (req->state == STATE_READ_BODY) { while (read_body(req, 0) >0); } req->ping = now; } if ((wset != NULL) && FD_ISSET(req->fd, wset)) { write_request(req); req->ping = now; } /* check timeouts */ if (req->state == STATE_KEEPALIVE) { if (now > req->ping + keepalive_time || curr_conn > max_conn * 9 / 10) { #ifdef DEBUG fprintf(stderr,"%03d/%d: keepalive timeout\n",req->fd,req->state); #endif req->state = STATE_CLOSE; } } else { if (now > req->ping + timeout) { if ((req->state == STATE_READ_HEADER) || (req->state == STATE_READ_BODY)) { mkerror(req,408,0); } else { log_error_func(0,LOG_INFO,"network timeout",req->peerhost); req->state = STATE_CLOSE; } } } /* parsing */ parsing: if (req->state == STATE_PARSE_HEADER) { parse_request(req, server_host); } /* body parsing */ if (req->state == STATE_PARSE_BODY) { parse_request_body(req); } if (req->state == STATE_WRITE_HEADER) { /* switch to writing */ FD_CLR(req->fd, &fds->rset); FD_SET(req->fd, &fds->wset); write_request(req); } /* handle finished requests */ if (req->state == STATE_FINISHED && !req->keep_alive) { req->state = STATE_CLOSE; } if (req->state == STATE_FINISHED) { /* access log hook */ if (log_request_func != NULL) { log_request_func(req, now); } /* switch to reading */ FD_CLR(req->fd, &fds->wset); FD_SET(req->fd, &fds->rset); /* cleanup */ req->auth[0] = 0; req->if_modified = 0; req->if_unmodified = 0; req->if_range = 0; req->range_hdr = NULL; req->ranges = 0; if (req->r_start) { free(req->r_start); req->r_start = NULL; } if (req->r_end) { free(req->r_end); req->r_end = NULL; } if (req->r_head) { free(req->r_head); req->r_head = NULL; } if (req->r_hlen) { free(req->r_hlen); req->r_hlen = NULL; } list_free(&req->header); if (req->bfd != -1) { close(req->bfd); req->bfd = -1; } /* free memory of response body */ if ((req->status<400) && (req->body != NULL)) { free(req->body); req->body = NULL; } req->written = 0; req->head_only = 0; req->rh = 0; req->rb = 0; req->hostname[0] = 0; req->path[0] = 0; req->query[0] = 0; req->lifespan = -1; if (req->hdata == (req->lreq + req->lbreq)) { /* ok, wait for the next one ... */ #ifdef DEBUG fprintf(stderr,"%03d/%d: keepalive wait\n",req->fd,req->state); #endif req->state = STATE_KEEPALIVE; req->hdata = 0; req->lreq = 0; req->lbreq = 0; #ifdef TCP_CORK if (req->tcp_cork == 1) { req->tcp_cork = 0; #ifdef DEBUG fprintf(stderr,"%03d/%d: tcp_cork=%d\n",req->fd,req->state,req->tcp_cork); #endif setsockopt(req->fd,SOL_TCP,TCP_CORK,&req->tcp_cork,sizeof(int)); } #endif } else { /* there is a pipelined request in the queue ... */ #ifdef DEBUG fprintf(stderr,"%03d/%d: keepalive pipeline\n",req->fd,req->state); #endif req->state = STATE_READ_HEADER; memmove(req->hreq,req->hreq + req->lreq + req->lbreq, req->hdata - (req->lreq + req->lbreq)); req->hdata -= req->lreq + req->lbreq; req->lreq = 0; read_header(req,1); goto parsing; } } /* connections to close */ if (req->state == STATE_CLOSE) { /* access log hook */ /*if (log_request_func != NULL) { log_request_func(req, now); }*/ FD_CLR(req->fd, &fds->rset); FD_CLR(req->fd, &fds->wset); /* leave max as is */ /* cleanup */ close(req->fd); #ifdef USE_SSL if (with_ssl) { SSL_free(req->ssl_s); } #endif if (req->bfd != -1) { close(req->bfd); #ifdef USE_SSL if (with_ssl) { BIO_vfree(req->bio_in); } #endif } curr_conn--; #ifdef DEBUG fprintf(stderr,"%03d/%d: done (%d)\n",req->fd,req->state,curr_conn); #endif /* unlink from list */ tmp = req; if (prev == NULL) { conns = req->next; req = conns; } else { prev->next = req->next; req = req->next; } /* free memory */ if (tmp->r_start) { free(tmp->r_start); } if (tmp->r_end) { free(tmp->r_end); } if (tmp->r_head) { free(tmp->r_head); } if (tmp->r_hlen) { free(tmp->r_hlen); } list_free(&tmp->header); free(tmp); } else { prev = req; req = req->next; } } return 0; }
static void remote_send_cb(EV_P_ ev_io *w, int revents) { remote_ctx_t *remote_send_ctx = (remote_ctx_t *)w; remote_t *remote = remote_send_ctx->remote; server_t *server = remote->server; if (!remote_send_ctx->connected) { struct sockaddr_storage addr; socklen_t len = sizeof addr; int r = getpeername(remote->fd, (struct sockaddr *)&addr, &len); if (r == 0) { remote_send_ctx->connected = 1; ev_io_stop(EV_A_ & remote_send_ctx->io); ev_timer_stop(EV_A_ & remote_send_ctx->watcher); // send destaddr buffer_t ss_addr_to_send; buffer_t *abuf = &ss_addr_to_send; balloc(abuf, BUF_SIZE); if (AF_INET6 == server->destaddr.ss_family) { // IPv6 abuf->array[abuf->len++] = 4; // Type 4 is IPv6 address size_t in6_addr_len = sizeof(struct in6_addr); memcpy(abuf->array + abuf->len, &(((struct sockaddr_in6 *)&(server->destaddr))->sin6_addr), in6_addr_len); abuf->len += in6_addr_len; memcpy(abuf->array + abuf->len, &(((struct sockaddr_in6 *)&(server->destaddr))->sin6_port), 2); } else { // IPv4 abuf->array[abuf->len++] = 1; // Type 1 is IPv4 address size_t in_addr_len = sizeof(struct in_addr); memcpy(abuf->array + abuf->len, &((struct sockaddr_in *)&(server->destaddr))->sin_addr, in_addr_len); abuf->len += in_addr_len; memcpy(abuf->array + abuf->len, &((struct sockaddr_in *)&(server->destaddr))->sin_port, 2); } abuf->len += 2; if (auth) { abuf->array[0] |= ONETIMEAUTH_FLAG; ss_onetimeauth(abuf, server->e_ctx->evp.iv, BUF_SIZE); } int err = ss_encrypt(abuf, server->e_ctx, BUF_SIZE); if (err) { bfree(abuf); LOGE("invalid password or cipher"); close_and_free_remote(EV_A_ remote); close_and_free_server(EV_A_ server); return; } int s = send(remote->fd, abuf->array, abuf->len, 0); bfree(abuf); if (s < abuf->len) { LOGE("failed to send addr"); close_and_free_remote(EV_A_ remote); close_and_free_server(EV_A_ server); return; } ev_io_start(EV_A_ & server->recv_ctx->io); ev_io_start(EV_A_ & remote->recv_ctx->io); return; } else { ERROR("getpeername"); // not connected close_and_free_remote(EV_A_ remote); close_and_free_server(EV_A_ server); return; } } else { if (remote->buf->len == 0) { // close and free close_and_free_remote(EV_A_ remote); close_and_free_server(EV_A_ server); return; } else { // has data to send ssize_t s = send(remote->fd, remote->buf->array + remote->buf->idx, remote->buf->len, 0); if (s < 0) { if (errno != EAGAIN && errno != EWOULDBLOCK) { ERROR("send"); // close and free close_and_free_remote(EV_A_ remote); close_and_free_server(EV_A_ server); } return; } else if (s < remote->buf->len) { // partly sent, move memory, wait for the next time to send remote->buf->len -= s; remote->buf->idx += s; return; } else { // all sent out, wait for reading remote->buf->len = 0; remote->buf->idx = 0; ev_io_stop(EV_A_ & remote_send_ctx->io); ev_io_start(EV_A_ & server->recv_ctx->io); } } } }
void Server::clientHandler(void * useless) { SOCKET clientSock; struct sockaddr_in clientSockAddr; struct CLIENT_DATA * clientData; std::vector<CLIENT_DATA*> serverSocksCopy; unsigned long iMode = 1; int addrLength = sizeof(clientSockAddr); while(isServerStopped == false) { #ifdef _WIN32 clientSock = accept(serverSock, (struct sockaddr *) &clientSockAddr, 0); //winapi basically cripples *BSD sox #else clientSock = accept(serverSock, (struct sockaddr *) &clientSockAddr, (socklen_t *) &addrLength); #endif cout << "clientSock: " << clientSock << " (INVALID_SOCKET is " << INVALID_SOCKET << "\n"; cout << strerror(errno) << "\n"; if(clientSock != INVALID_SOCKET) { #ifdef _WIN32 ioctlsocket(clientSock, FIONBIO, &iMode); //non-blocking mode #else ioctl(clientSock, FIONBIO, &iMode); #endif /*now we've gotten a client, let's give em a struct*/ clientData = new CLIENT_DATA; /*this is unallocated in serverTick()*/ { clientData->index = grabAvailableIndex(); //clientData->isConnected = true; //un-necassary: if the client is not connected, they will not be in the list. clientData->sock = clientSock; #ifdef _WIN32 getpeername(clientSock, (sockaddr *)&clientSockAddr, &addrLength); /*grab updated client sockaddr_in structure*/ #else getpeername(clientSock, (sockaddr *)&clientSockAddr, (socklen_t *) &addrLength); #endif #ifdef _WIN32 clientData->ip.compileIPLongToBytes(clientSockAddr.sin_addr.S_un.S_addr); //update our IPAddress structure #else clientData->ip.compileIPLongToBytes(clientSockAddr.sin_addr.s_addr); #endif clientData->port = htons(clientSockAddr.sin_port); serverSocks.push_back(clientData); //cout << "New client: \n" << "Sock: " << clientData->sock << "\nIP: " << clientData->ip.ipString << "\nIndex: " << clientData->index << "\n"; cout << "(Server: " << port << ") [C] " << clientData->ip.ipString << ":" << clientData->port << " [S.I.:" << clientData->index << "] (" << connectedClients() << " clients connected)\n"; //cout << "new connection\n"; } } } }
static int proto (int sock, const char *service) { struct sockaddr_storage remote, local; socklen_t addrlen; krb5_address remote_addr, local_addr; krb5_ccache ccache; krb5_auth_context auth_context; krb5_error_code status; krb5_data packet; krb5_data data; krb5_data client_name; krb5_creds in_creds, *out_creds; addrlen = sizeof(local); if (getsockname (sock, (struct sockaddr *)&local, &addrlen) < 0 || addrlen > sizeof(local)) err (1, "getsockname)"); addrlen = sizeof(remote); if (getpeername (sock, (struct sockaddr *)&remote, &addrlen) < 0 || addrlen > sizeof(remote)) err (1, "getpeername"); status = krb5_auth_con_init (context, &auth_context); if (status) krb5_err(context, 1, status, "krb5_auth_con_init"); status = krb5_sockaddr2address (context, (struct sockaddr *)&local, &local_addr); if (status) krb5_err(context, 1, status, "krb5_sockaddr2address(local)"); status = krb5_sockaddr2address (context, (struct sockaddr *)&remote, &remote_addr); if (status) krb5_err(context, 1, status, "krb5_sockaddr2address(remote)"); status = krb5_auth_con_setaddrs (context, auth_context, &local_addr, &remote_addr); if (status) krb5_err(context, 1, status, "krb5_auth_con_setaddr"); status = krb5_read_message(context, &sock, &client_name); if(status) krb5_err(context, 1, status, "krb5_read_message"); memset(&in_creds, 0, sizeof(in_creds)); status = krb5_cc_default(context, &ccache); if(status) krb5_err(context, 1, status, "krb5_cc_default"); status = krb5_cc_get_principal(context, ccache, &in_creds.client); if(status) krb5_err(context, 1, status, "krb5_cc_get_principal"); status = krb5_read_message(context, &sock, &in_creds.second_ticket); if(status) krb5_err(context, 1, status, "krb5_read_message"); status = krb5_parse_name(context, client_name.data, &in_creds.server); if(status) krb5_err(context, 1, status, "krb5_parse_name"); status = krb5_get_credentials(context, KRB5_GC_USER_USER, ccache, &in_creds, &out_creds); if(status) krb5_err(context, 1, status, "krb5_get_credentials"); status = krb5_cc_default(context, &ccache); if(status) krb5_err(context, 1, status, "krb5_cc_default"); status = krb5_sendauth(context, &auth_context, &sock, VERSION, in_creds.client, in_creds.server, AP_OPTS_USE_SESSION_KEY, NULL, out_creds, ccache, NULL, NULL, NULL); if (status) krb5_err(context, 1, status, "krb5_sendauth"); { char *str; krb5_unparse_name(context, in_creds.server, &str); printf ("User is `%s'\n", str); free(str); krb5_unparse_name(context, in_creds.client, &str); printf ("Server is `%s'\n", str); free(str); } krb5_data_zero (&data); krb5_data_zero (&packet); status = krb5_read_message(context, &sock, &packet); if(status) krb5_err(context, 1, status, "krb5_read_message"); status = krb5_rd_safe (context, auth_context, &packet, &data, NULL); if (status) krb5_err(context, 1, status, "krb5_rd_safe"); printf ("safe packet: %.*s\n", (int)data.length, (char *)data.data); status = krb5_read_message(context, &sock, &packet); if(status) krb5_err(context, 1, status, "krb5_read_message"); status = krb5_rd_priv (context, auth_context, &packet, &data, NULL); if (status) krb5_err(context, 1, status, "krb5_rd_priv"); printf ("priv packet: %.*s\n", (int)data.length, (char *)data.data); return 0; }
/* * We've initiated all connection attempts. * Here we sit and wait for them to complete. */ static void waitforconnects() { fd_set writefds, exceptfds; struct timeval timeleft; struct timeval starttime; struct timeval curtime; struct timeval timeoutval; struct timeval timeused; struct sockaddr_in dummysock; int dummyint = sizeof(dummysock); int numfds; int res; int i; gettimeofday(&starttime, NULL); timeoutval.tv_sec = timeout; timeoutval.tv_usec = 0; timeleft = timeoutval; while (1) { FD_ZERO(&writefds); FD_ZERO(&exceptfds); setupset(&writefds, &numfds); setupset(&exceptfds, &numfds); res = select(numfds+1, NULL, &writefds, &exceptfds, &timeleft); if (res == -1) { perror("select barfed, bailing"); exit(-1); } if (res == 0) /* We timed out */ break; /* Oooh. We have some successes */ /* First test the exceptions */ for (i = 0; i < numcons; i++) { if (cons[i] == NULL) continue; if (FD_ISSET(cons[i]->socket, &exceptfds)) { failedconnect(i); } else if (FD_ISSET(cons[i]->socket, &writefds)) { /* Boggle. It's not always good. select() is weird. */ if (getpeername(cons[i]->socket, (struct sockaddr *)&dummysock, &dummyint)) failedconnect(i); else goodconnect(i); } } /* now, timeleft = timeoutval - timeused */ gettimeofday(&curtime, NULL); subtime(&curtime, &starttime, &timeused); subtime(&timeoutval, &timeused, &timeleft); } /* Now clean up the remainder... they timed out. */ for (i = 0; i < numcons; i++) { if (cons[i]->status == 0) { printf("%s:%d failed: timed out\n", cons[i]->hostname, cons[i]->port); } } }
/* 返回2:进入异步 */ int CTcpClient::WaitConnect(int *piRet, char *psRet) { int m_iRet; int m_iRet2; char m_sRet[256]; fd_set writefds; struct timeval timeout; int ret; struct sockaddr name2; #ifdef MAC_OS socklen_t nameLen = sizeof(name2); #else SOCKADDRLEN nameLen=sizeof(name2); #endif m_iRet = 0; m_iRet2 =0; strcpy(m_sRet,""); /* 1. 如果已经连接,则返回成功! */ if (m_bIsConnected == true) { m_iRet = 0; m_iRet2 = 1; strcpy(m_sRet,"已经连接成功!"); goto L_RET; } /* 2. 如果还没有开始连接,则返回失败 */ if (m_bIsConnecting == false) { m_iRet = 0; m_iRet2 = 0; strcpy(m_sRet,"尚未开始连接"); goto L_RET; } /* use select to wait for it */ FD_ZERO(&writefds); FD_SET(m_id,&writefds); timeout.tv_sec=0; timeout.tv_usec=100; ret=select(m_id+1,NULL,&writefds,NULL,&timeout); /* timeout? then return with fail */ if (ret==0) { m_iRet2 =2 ; m_iRet = 0; strcpy(m_sRet,""); goto L_RET; } /* recheck whether connected */ // printf("Getpeername:%d,%d\n",ret,GET_LAST_SOCK_ERROR()); if ((ret>0)&&FD_ISSET(m_id,&writefds)) { nameLen=sizeof(name2); memset(&name2,0,sizeof(name2)); ret =getpeername(m_id,(sockaddr*)&name2,&nameLen); if (ret ==0) { m_iRet = 0; m_iRet2 = 1; m_bIsConnecting = false; m_bIsConnected = true; goto L_RET; } /* 这个很奇怪,连接某些时候就是getpeername会失败,返回EINVAL,可能和服务端有关? */ if (GET_LAST_SOCK_ERROR()==EINVAL) { m_iRet = 0; m_iRet2 = 1; m_bIsConnecting = false; m_bIsConnected = true; goto L_RET; } // printf("Getpeername:%d,%d\n",ret,GET_LAST_SOCK_ERROR()); } m_iRet = -1; m_iRet2 = 0; sprintf(m_sRet,"Can not connect to Server[%d]!",GET_LAST_SOCK_ERROR()); CloseSocket(); L_RET: if (piRet) *piRet = m_iRet; if (psRet) strcpy(psRet,m_sRet); return m_iRet2; }
int main(void) { int sockfd; struct addrinfo hints, *servinfo, *p; int rv; int numbytes; char din[100][100] = {0}; FILE *fp; fp = fopen("doc1.txt","r"); int m; for(m=0;m<6;m++){ fscanf(fp,"%s",din[m]); } struct hostent *lh;//get IP address of localhost struct in_addr **addr_list; lh = gethostbyname("localhost"); addr_list = (struct in_addr **)lh->h_addr_list; printf("Phase 3: Doctor1 has a static port number 41414 "); int z; for(z = 0; addr_list[z] != NULL; z++) { printf("and IP address %s ", inet_ntoa(*addr_list[z])); } printf("\n"); struct sockaddr_storage their_addr; char buf[MAXBUFLEN]; socklen_t addr_len; char s[INET6_ADDRSTRLEN]; memset(&hints, 0, sizeof hints); hints.ai_family = AF_UNSPEC; // set to AF_INET to force IPv4 hints.ai_socktype = SOCK_DGRAM; hints.ai_flags = AI_PASSIVE; // use my IP if ((rv = getaddrinfo(NULL, MYPORT, &hints, &servinfo)) != 0) { fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv)); return 1; } // loop through all the results and bind to the first we can for(p = servinfo; p != NULL; p = p->ai_next) { if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) { perror("listener: socket"); continue; } if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) { close(sockfd); perror("listener: bind"); continue; } break; } if (p == NULL) { fprintf(stderr, "listener: failed to bind socket\n"); return 2; } freeaddrinfo(servinfo); while(1) { addr_len = sizeof their_addr; if ((numbytes = recvfrom(sockfd, buf, MAXBUFLEN-1 , 0, (struct sockaddr *)&their_addr, &addr_len)) == -1) { perror("recvfrom"); exit(1); } buf[numbytes] = '\0'; printf("%s\n",buf); char c1[]=" "; char un[20]; char ins[20]; char *p1=strtok(buf,c1); memcpy(un, p1, 20); p1 = strtok(NULL,c1); memcpy(ins, p1, 20); struct sockaddr_in addrudp; memset(&addrudp,10,sizeof(addrudp)); int lenudp = sizeof addrudp; char cip[20]; getpeername(sockfd, (struct sockaddr *)&addrudp, (socklen_t *)&lenudp); inet_ntop(AF_INET, &addrudp.sin_addr, cip, sizeof cip); int portudp=addrudp.sin_port; printf("Phase 3: Doctor 1 receives the request from the patient with port number %d and name %s with the insurance plan %s.\n",portudp,un,ins); if(strcmp(ins,"insurance1")==0){ printf("Phase 3: Doctor 1 has sent estimated price $%s to patient named %s with port number %d.\n",din[1],un,portudp); if ((numbytes = sendto(sockfd, din[1],100, 0, (struct sockaddr *)&their_addr, addr_len)) == -1) { perror("talker: sendto"); exit(1); } } if(strcmp(ins,"insurance2")==0){ printf("Phase 3: Doctor 1 has sent estimated price $%s to patient named %s with port number %d.\n",din[3],un,portudp); if ((numbytes = sendto(sockfd, din[3],100, 0, (struct sockaddr *)&their_addr, addr_len)) == -1) { perror("talker: sendto"); exit(1); } } if(strcmp(ins,"insurance3")==0){ printf("Phase 3: Doctor 1 has sent estimated price $%s to patient named %s with port number %d.\n",din[5],un,portudp); if ((numbytes = sendto(sockfd, din[5],100, 0, (struct sockaddr *)&their_addr, addr_len)) == -1) { perror("talker: sendto"); exit(1); } } } close(sockfd); return 0; }
int main(int argc, char *argv[]) { fd_set master, read_fds; int fdmax,sockfd,newfd,yes=1,addrlen,i,j,size; struct sockaddr_in my_addr, their_addr,client_addr; //Server and Client IP address char inputbuf[MAX_INPUT_SIZE],buffer[10]; size=sizeof(struct sockaddr); FD_ZERO(&master); //Clear master ans temp sets. FD_ZERO(&read_fds); if(argc!=2) //Check if no. of arguments are correct. { fprintf(stderr,"Wrong number of arguments provided.\n"); exit(1); } for(i = 0; i < strlen(argv[1]); ++i) { if(isdigit(argv[1][i])==0) //Check if only digits are given as input. { fprintf(stderr,"Port number should be a number.\n"); exit(1); } } int port_no=atoi(argv[1]); //Convert port no. to interger. if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1) //Make a socket. { perror("socket"); exit(3); } if(setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int))==-1) { perror("setsockopt"); exit(3); } my_addr.sin_family = AF_INET; my_addr.sin_port = htons(port_no); my_addr.sin_addr.s_addr = INADDR_ANY; memset(&(my_addr.sin_zero), '\0', 8); if(bind(sockfd,(struct sockaddr *)&my_addr,sizeof(struct sockaddr))==-1) //Check bind and bid the socket with a sock address. { perror("bind"); exit(2); } if(listen(sockfd,BACKLOG)==-1) //Listening on a port. { perror("listen"); exit(3); } FD_SET(sockfd,&master); //Add the socket to the master set. fdmax=sockfd; while(1) //The server waits for listening from a client even when all the previous connections are closed. { read_fds=master; if (select(fdmax+1,&read_fds,NULL,NULL,NULL)==-1) { perror("select"); end(3); } for(i=0;i<=fdmax;i++) //Looking for data to read from existing connections. { if(FD_ISSET(i,&read_fds)) //Data to read found. { if(i==sockfd) { addrlen=sizeof(their_addr); //New connections. if((newfd=accept(sockfd,(struct sockaddr *)&their_addr,&addrlen))==-1) { perror("accept"); } else { FD_SET(newfd,&master); //Adding socket to master set. if(newfd>fdmax) //Update maximum if changed. { fdmax=newfd; } } } else { recv(i,inputbuf,sizeof(inputbuf),0); if(inputbuf[0]=='B' && inputbuf[1]=='y' && inputbuf[2]=='e' && inputbuf[3]=='\n') { getpeername(i,(struct sockaddr *)&client_addr,&size); strcpy(inputbuf,"Goodbye "); strcat(inputbuf,inet_ntoa(client_addr.sin_addr)); strcat(inputbuf,":"); sprintf(buffer,"%d",ntohs(client_addr.sin_port)); strcat(inputbuf,buffer); send(i,inputbuf,strlen(inputbuf),0); close(i); //Closing the connection. FD_CLR(i,&master); //Removing socket from master set. } else if(inputbuf[0]=='L' && inputbuf[1]=='i' && inputbuf[2]=='s' && inputbuf[3]=='t' && inputbuf[4]=='\n') { strcpy(inputbuf,"OK "); //Printing the socket which is asking for List. getpeername(i,(struct sockaddr *)&client_addr,&size); strcat(inputbuf,inet_ntoa(client_addr.sin_addr)); strcat(inputbuf,":"); sprintf(buffer,"%d",ntohs(client_addr.sin_port)); strcat(inputbuf,buffer); for(j=0;j<=fdmax;j++) { if(FD_ISSET(j,&master)) { if(j!=sockfd && j!=i) //The other sockets in the master set. { strcat(inputbuf,", "); getpeername(j,(struct sockaddr *)&client_addr,&size); strcat(inputbuf,inet_ntoa(client_addr.sin_addr)); strcat(inputbuf,":"); sprintf(buffer,"%d",ntohs(client_addr.sin_port)); strcat(inputbuf,buffer); } } } send(i,inputbuf,strlen(inputbuf),0); //Printing the whole list of sockets. } else { getpeername(i,(struct sockaddr *)&client_addr,&size); strcpy(inputbuf,"OK "); strcat(inputbuf,inet_ntoa(client_addr.sin_addr)); strcat(inputbuf,":"); sprintf(buffer,"%d",ntohs(client_addr.sin_port)); strcat(inputbuf,buffer); send(i,inputbuf,strlen(inputbuf),0); } } } } } close(sockfd); return 0; }