int main(int argc, char **argv) { int sockfd; socklen_t len; struct sockaddr_un addr1, addr2; if (argc != 2) err_quit("usage: unixbind <pathname>"); sockfd = Socket(AF_LOCAL, SOCK_STREAM, 0); unlink(argv[1]); /* OK if this fails */ bzero(&addr1, sizeof(addr1)); addr1.sun_family = AF_LOCAL; strncpy(addr1.sun_path, argv[1], sizeof(addr1.sun_path)-1); Bind(sockfd, (SA *) &addr1, SUN_LEN(&addr1)); len = sizeof(addr2); Getsockname(sockfd, (SA *) &addr2, &len); printf("bound name = %s, returned len = %d\n", addr2.sun_path, len); exit(0); }
int main(int argc, char **argv) { int sockfd; socklen_t len; struct sockaddr_in cliaddr, servaddr; if (argc != 2) err_quit("usage: udpcli <IPaddress>"); sockfd = Socket(AF_INET, SOCK_DGRAM, 0); bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(SERV_PORT); Inet_pton(AF_INET, argv[1], &servaddr.sin_addr); Connect(sockfd, (SA *) &servaddr, sizeof(servaddr)); len = sizeof(cliaddr); Getsockname(sockfd, (SA *) &cliaddr, &len); printf("local address %s\n", Sock_ntop((SA *) &cliaddr, len)); exit(0); }
int main(int argc, char const *argv[]) { int family = AF_INET; if (!(argc ==3 || argc ==4)) err_sys("input args: address port"); if (argc == 4) family = AF_INET6; struct sockaddr *serv_addr; socklen_t serv_len; if (family == AF_INET){ serv_addr = (struct sockaddr*)v4_addr(family, atoi(argv[2]), argv[1]); serv_len = sizeof(struct sockaddr_in); } else { serv_addr = (struct sockaddr*)v6_addr(family, atoi(argv[2]), argv[1]); serv_len = sizeof(struct sockaddr_in6); } int clientfd = Socket(family, SOCK_STREAM, IPPROTO_TCP); Connect(clientfd, serv_addr, serv_len); struct sockaddr local_addr; Getsockname(clientfd, &local_addr, &serv_len); print_ip_addr(family, &local_addr, "local address \n"); select_do(clientfd); Close(clientfd); free(serv_addr); return 0; }
int main(int argc, char* argv[]){ int family = AF_INET6; int servfd=Socket(family, SOCK_STREAM, IPPROTO_TCP); Listen(servfd, 0); struct sockaddr_in6 cliaddr; socklen_t len = sizeof(cliaddr); int clientfd; char buf[MAXLINE]; struct sockaddr_in6 servaddr; socklen_t slen = sizeof(servaddr); char buf1[MAXLINE]; Getsockname(servfd, (struct sockaddr*)&servaddr, &slen); printf("server bind address: %s, port %d\n", inet_ntop(family, &servaddr.sin6_addr, buf1, sizeof(buf1)), ntohs(servaddr.sin6_port)); for ( ; ;) { clientfd = Accept(servfd, (struct sockaddr*)&cliaddr, &len); printf("connect from %s, port %d\n", inet_ntop(family, &cliaddr.sin6_addr, buf, sizeof(buf)), ntohs(cliaddr.sin6_port)); bzero(&cliaddr, sizeof(cliaddr)); Close(clientfd); } }
// Connect to the server, and send the first datagram void initiate_tx(void) { sockfd = Socket(AF_INET, SOCK_DGRAM, 0); if (conn->is_local) { set_dontroute(sockfd); } // Bind to port 0 Bind(sockfd, conn->cli_sa, (socklen_t)sizeof(SA)); struct sockaddr_in sin; UINT addrlen = sizeof(SA); // Fetch port number at which kernel bound this socket. Getsockname(sockfd, (SA *)&sin, &addrlen); cliport = ntohs(sin.sin_port); INFO("Client's ephemeral Port Number: %d\n", cliport); // Connect to the server. Connect(sockfd, conn->serv_sa, sizeof(SA)); // TODO // Do we need getpeername here? // Start a timer here to re-send the file name till we receive an // ACK. struct timeval timeout; timeout.tv_sec = 3; timeout.tv_usec = 0; fdset_init(&fds, timeout, ack_timeout); fdset_add(&fds, &fds.rev, sockfd, &sockfd, send_file); fdset_add(&fds, &fds.exev, sockfd, &sockfd, handle_tx_error); // Send the packet to the server INFO("Trying to send the SYN packet to the Server with the file name%s\n", ""); send_filename_pkt(); int r = fdset_poll2(&fds); if (r < 0) { perror("select"); ASSERT(errno != EINTR); exit(1); } }
int main(int argc, char* argv[]) { int family = AF_INET; if (argc == 2) { family = (atoi(argv[1]) == 6)? AF_INET6 : AF_INET; } int servfd = Socket(family, SOCK_STREAM, IPPROTO_TCP); Listen(servfd, 0); struct sockaddr local_addr; socklen_t len = (family == AF_INET) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6); Getsockname(servfd, &local_addr, &len); print_ip_addr(family, &local_addr, "local address:"); select_do(servfd, family); Close(servfd); }
void *sock_port_mapper(void *arg){ struct sockaddr_in server_sockaddr, client_sockaddr; int sin_size, recvbytes, sendbytes; int sockfd, client_fd, desc_ready; char logmsg[128]; sin_size=sizeof(client_sockaddr); /* Data structure to handle timeout */ struct timeval before, timer, *tvptr; struct timezone tzp; /* Data structure for the select I/O */ fd_set ready_set, test_set; int maxfd, nready, client[FD_SETSIZE]; /* create socket */ sockfd = Socket(AF_INET,SOCK_STREAM,0); /* set parameters for sockaddr_in */ server_sockaddr.sin_family = AF_INET; server_sockaddr.sin_port = htons(PORT); //0, assign port automatically in 1024 ~ 65535 server_sockaddr.sin_addr.s_addr = htonl(INADDR_ANY); //0, got local IP automatically bzero(&(server_sockaddr.sin_zero), 8); int i = 1;//enable reuse the combination of local address and socket setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i)); Bind(sockfd, server_sockaddr); getaddr(hostname, addrstr); //get hostname and ip, getaddrinfo.h port = Getsockname(sockfd, server_sockaddr, sin_size); /* Get the port number assigned*/ writePortMapper(port, addrstr, PORT_MAPPER_FILE); snprintf(logmsg, sizeof(logmsg), "sockserver: Server %s (%s) is setup on port: %d\n", addrstr, hostname, port); logging(LOGFILE, logmsg); Listen(sockfd, MAX_QUE_CONN_NM); /* Thread attribute */ pthread_attr_t attr; pthread_attr_init(&attr); // Creating thread attributes pthread_attr_setschedpolicy(&attr, SCHED_RR); // Round Robin scheduling for threads pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); // Don't want threads (particualrly main) int iThread = 0; // Thread iterator /* Set up the I/O for the socket, nonblocking */ maxfd = sockfd; int k; for(k=0;k<FD_SETSIZE;k++){ client[k] = -1; } FD_ZERO(&ready_set); FD_ZERO(&test_set); FD_SET(sockfd, &test_set); /* Initialize the timeval struct to TIMER seconds */ timer.tv_sec = TIMER; timer.tv_usec = 0; tvptr = &timer; /* Set up the time out by getting the time of the day from the system */ gettimeofday(&before, &tzp); int status; status=CONTINUE; while (status==CONTINUE){ if (iThread == NTHREADS){ iThread = 0; } memcpy(&ready_set, &test_set, sizeof(test_set)); nready = select(maxfd+1, &ready_set, NULL, NULL, tvptr); switch(nready){ case -1: printf("sockserver: errno: %d.\n", errno); perror("\nSELECT: unexpected error occured.\n"); logging(LOGFILE, "\nSELECT: unexpected error occured.\n"); /* remove bad fd */ for(k=0;k<FD_SETSIZE;k++){ if(client[k] > 0){ struct stat tStat; if (-1 == fstat(client[k], &tStat)){ printf("fstat %d error:%s", sockfd, strerror(errno)); FD_CLR(client[k], &ready_set); } } } status=-1; break; case 0: /* timeout occuired */ printf("sockserver: TIMEOUT... %d.\n", errno); status=-1; break; default: if (FD_ISSET(sockfd, &ready_set)){ //snprintf(logmsg, sizeof(logmsg), "sockserver(0x%x): Listening socket is readable\n", pthread_self()); //logging(LOGFILE, logmsg); /* wait for connection */ client_fd = Accept(sockfd, client_sockaddr, sin_size); for(k=0;k<FD_SETSIZE;k++){ if(client[k] < 0){ client[k] = client_fd; } } FD_SET(client_fd, &test_set); if (client_fd > maxfd) maxfd = client_fd; snprintf(logmsg, sizeof(logmsg), "sockserver(0x%x): Descriptor %d is readable\n", pthread_self(), client_fd); logging(LOGFILE, logmsg); pthread_create(&threadid[iThread], &attr, &port_mapper_thread, (void *)client_fd); pthread_join(threadid[iThread], NULL); iThread++; }// end if (FD_ISSET(i, &ready_set)) }// end switch usleep(100); } // end while (status==CONTINUE) close(sockfd); unlinkPortFile(addrstr); return 0; }
/* we expect the form: port */ int xioopen_ipdgram_listen(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, unsigned groups, int pf, int ipproto, int protname) { const char *portname = argv[1]; union sockaddr_union us; union sockaddr_union themunion; union sockaddr_union *them = &themunion; int socktype = SOCK_DGRAM; struct pollfd readfd; bool dofork = false; pid_t pid; char *rangename; char infobuff[256]; unsigned char buff1[1]; socklen_t uslen; socklen_t themlen; int result; if (argc != 2) { Error2("%s: wrong number of parameters (%d instead of 1)", argv[0], argc-1); } if (pf == PF_UNSPEC) { #if WITH_IP4 && WITH_IP6 pf = xioopts.default_ip=='6'?PF_INET6:PF_INET; #elif WITH_IP6 pf = PF_INET6; #else pf = PF_INET; #endif } retropt_socket_pf(opts, &pf); if (applyopts_single(&fd->stream, opts, PH_INIT) < 0) return -1; applyopts(-1, opts, PH_INIT); uslen = socket_init(pf, &us); retropt_bind(opts, pf, socktype, IPPROTO_UDP, (struct sockaddr *)&us, &uslen, 1, fd->stream.para.socket.ip.res_opts[1], fd->stream.para.socket.ip.res_opts[0]); if (false) { ; #if WITH_IP4 } else if (pf == PF_INET) { us.ip4.sin_port = parseport(portname, ipproto); #endif #if WITH_IP6 } else if (pf == PF_INET6) { us.ip6.sin6_port = parseport(portname, ipproto); #endif } else { Error1("xioopen_ipdgram_listen(): unknown address family %d", pf); } retropt_bool(opts, OPT_FORK, &dofork); if (dofork) { if (!(xioflags & XIO_MAYFORK)) { Error("option fork not allowed here"); return STAT_NORETRY; } } #if WITH_IP4 /*|| WITH_IP6*/ if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) { if (xioparserange(rangename, pf, &fd->stream.para.socket.range) < 0) { free(rangename); return STAT_NORETRY; } free(rangename); fd->stream.para.socket.dorange = true; } #endif #if WITH_LIBWRAP xio_retropt_tcpwrap(&fd->stream, opts); #endif /* WITH_LIBWRAP */ if (retropt_ushort(opts, OPT_SOURCEPORT, &fd->stream.para.socket.ip.sourceport) >= 0) { fd->stream.para.socket.ip.dosourceport = true; } retropt_bool(opts, OPT_LOWPORT, &fd->stream.para.socket.ip.lowport); if (dofork) { xiosetchilddied(); /* set SIGCHLD handler */ } while (true) { /* we loop with fork or prohibited packets */ /* now wait for some packet on this datagram socket, get its sender address, connect there, and return */ int one = 1; char infobuff[256]; union sockaddr_union _sockname; union sockaddr_union *la = &_sockname; /* local address */ if ((fd->stream.fd = xiosocket(opts, pf, socktype, ipproto, E_ERROR)) < 0) { return STAT_RETRYLATER; } applyopts(fd->stream.fd, opts, PH_PASTSOCKET); if (Setsockopt(fd->stream.fd, opt_so_reuseaddr.major, opt_so_reuseaddr.minor, &one, sizeof(one)) < 0) { Warn6("setsockopt(%d, %d, %d, {%d}, "F_Zd"): %s", fd->stream.fd, opt_so_reuseaddr.major, opt_so_reuseaddr.minor, one, sizeof(one), strerror(errno)); } applyopts_cloexec(fd->stream.fd, opts); applyopts(fd->stream.fd, opts, PH_PREBIND); applyopts(fd->stream.fd, opts, PH_BIND); if (Bind(fd->stream.fd, &us.soa, uslen) < 0) { Error4("bind(%d, {%s}, "F_Zd"): %s", fd->stream.fd, sockaddr_info(&us.soa, uslen, infobuff, sizeof(infobuff)), uslen, strerror(errno)); return STAT_RETRYLATER; } /* under some circumstances bind() fills sockaddr with interesting info. */ if (Getsockname(fd->stream.fd, &us.soa, &uslen) < 0) { Error4("getsockname(%d, %p, {%d}): %s", fd->stream.fd, &us.soa, uslen, strerror(errno)); } applyopts(fd->stream.fd, opts, PH_PASTBIND); Notice1("listening on UDP %s", sockaddr_info(&us.soa, uslen, infobuff, sizeof(infobuff))); readfd.fd = fd->stream.fd; readfd.events = POLLIN|POLLERR; while (xiopoll(&readfd, 1, NULL) < 0) { if (errno != EINTR) break; } themlen = socket_init(pf, them); do { result = Recvfrom(fd->stream.fd, buff1, 1, MSG_PEEK, &them->soa, &themlen); } while (result < 0 && errno == EINTR); if (result < 0) { Error5("recvfrom(%d, %p, 1, MSG_PEEK, {%s}, {"F_Zu"}): %s", fd->stream.fd, buff1, sockaddr_info(&them->soa, themlen, infobuff, sizeof(infobuff)), themlen, strerror(errno)); return STAT_RETRYLATER; } Notice1("accepting UDP connection from %s", sockaddr_info(&them->soa, themlen, infobuff, sizeof(infobuff))); if (xiocheckpeer(&fd->stream, them, la) < 0) { /* drop packet */ char buff[512]; Recv(fd->stream.fd, buff, sizeof(buff), 0); /* drop packet */ Close(fd->stream.fd); continue; } Info1("permitting UDP connection from %s", sockaddr_info(&them->soa, themlen, infobuff, sizeof(infobuff))); if (dofork) { pid = xio_fork(false, E_ERROR); if (pid < 0) { return STAT_RETRYLATER; } if (pid == 0) { /* child */ break; } /* server: continue loop with socket()+recvfrom() */ /* when we dont close this we get awkward behaviour on Linux 2.4: recvfrom gives 0 bytes with invalid socket address */ if (Close(fd->stream.fd) < 0) { Info2("close(%d): %s", fd->stream.fd, strerror(errno)); } Sleep(1); /*! give child a chance to consume the old packet */ continue; } break; } applyopts(fd->stream.fd, opts, PH_CONNECT); if ((result = Connect(fd->stream.fd, &them->soa, themlen)) < 0) { Error4("connect(%d, {%s}, "F_Zd"): %s", fd->stream.fd, sockaddr_info(&them->soa, themlen, infobuff, sizeof(infobuff)), themlen, strerror(errno)); return STAT_RETRYLATER; } /* set the env vars describing the local and remote sockets */ if (Getsockname(fd->stream.fd, &us.soa, &uslen) < 0) { Warn4("getsockname(%d, %p, {%d}): %s", fd->stream.fd, &us.soa, uslen, strerror(errno)); } xiosetsockaddrenv("SOCK", &us, uslen, IPPROTO_UDP); xiosetsockaddrenv("PEER", them, themlen, IPPROTO_UDP); fd->stream.howtoend = END_SHUTDOWN; applyopts_fchown(fd->stream.fd, opts); applyopts(fd->stream.fd, opts, PH_LATE); if ((result = _xio_openlate(&fd->stream, opts)) < 0) return result; return 0; }
/* creates the listening socket, bind, applies options; waits for incoming connection, checks its source address and port. Depending on fork option, it may fork a subprocess. pf specifies the syntax expected for range option. In the case of generic socket it is 0 (expecting raw binary data), and the real pf can be obtained from us->af_family; for other socket types pf == us->af_family Returns 0 if a connection was accepted; with fork option, this is always in a subprocess! Other return values indicate a problem; this can happen in the master process or in a subprocess. This function does not retry. If you need retries, handle this in a loop in the calling function (and always provide the options...) After fork, we set the forever/retry of the child process to 0 applies and consumes the following option: PH_INIT, PH_PASTSOCKET, PH_PREBIND, PH_BIND, PH_PASTBIND, PH_EARLY, PH_PREOPEN, PH_FD, PH_CONNECTED, PH_LATE, PH_LATE2 OPT_FORK, OPT_SO_TYPE, OPT_SO_PROTOTYPE, OPT_BACKLOG, OPT_RANGE, tcpwrap, OPT_SOURCEPORT, OPT_LOWPORT, cloexec */ int _xioopen_listen(struct single *xfd, int xioflags, struct sockaddr *us, socklen_t uslen, struct opt *opts, int pf, int socktype, int proto, int level) { struct sockaddr sa; socklen_t salen; int backlog = 5; /* why? 1 seems to cause problems under some load */ char *rangename; bool dofork = false; int maxchildren = 0; char infobuff[256]; char lisname[256]; union sockaddr_union _peername; union sockaddr_union _sockname; union sockaddr_union *pa = &_peername; /* peer address */ union sockaddr_union *la = &_sockname; /* local address */ socklen_t pas = sizeof(_peername); /* peer address size */ socklen_t las = sizeof(_sockname); /* local address size */ int result; retropt_bool(opts, OPT_FORK, &dofork); if (dofork) { if (!(xioflags & XIO_MAYFORK)) { Error("option fork not allowed here"); return STAT_NORETRY; } xfd->flags |= XIO_DOESFORK; } retropt_int(opts, OPT_MAX_CHILDREN, &maxchildren); if (! dofork && maxchildren) { Error("option max-children not allowed without option fork"); return STAT_NORETRY; } if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1; if (dofork) { xiosetchilddied(); /* set SIGCHLD handler */ } if ((xfd->fd = xiosocket(opts, us->sa_family, socktype, proto, level)) < 0) { return STAT_RETRYLATER; } applyopts_cloexec(xfd->fd, opts); applyopts(xfd->fd, opts, PH_PREBIND); applyopts(xfd->fd, opts, PH_BIND); if (Bind(xfd->fd, (struct sockaddr *)us, uslen) < 0) { Msg4(level, "bind(%d, {%s}, "F_socklen"): %s", xfd->fd, sockaddr_info(us, uslen, infobuff, sizeof(infobuff)), uslen, strerror(errno)); Close(xfd->fd); return STAT_RETRYLATER; } #if WITH_UNIX if (us->sa_family == AF_UNIX) { applyopts_named(((struct sockaddr_un *)us)->sun_path, opts, PH_FD); } #endif /* under some circumstances (e.g., TCP listen on port 0) bind() fills empty fields that we want to know. */ salen = sizeof(sa); if (Getsockname(xfd->fd, us, &uslen) < 0) { Warn4("getsockname(%d, %p, {%d}): %s", xfd->fd, &us, uslen, strerror(errno)); } applyopts(xfd->fd, opts, PH_PASTBIND); #if WITH_UNIX if (us->sa_family == AF_UNIX) { /*applyopts_early(((struct sockaddr_un *)us)->sun_path, opts);*/ applyopts_named(((struct sockaddr_un *)us)->sun_path, opts, PH_EARLY); applyopts_named(((struct sockaddr_un *)us)->sun_path, opts, PH_PREOPEN); } #endif /* WITH_UNIX */ #if WITH_IP4 /*|| WITH_IP6*/ if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) { if (xioparserange(rangename, pf, &xfd->para.socket.range) < 0) { free(rangename); return STAT_NORETRY; } free(rangename); xfd->para.socket.dorange = true; } #endif #if (WITH_TCP || WITH_UDP) && WITH_LIBWRAP xio_retropt_tcpwrap(xfd, opts); #endif /* && (WITH_TCP || WITH_UDP) && WITH_LIBWRAP */ #if WITH_TCP || WITH_UDP if (retropt_ushort(opts, OPT_SOURCEPORT, &xfd->para.socket.ip.sourceport) >= 0) { xfd->para.socket.ip.dosourceport = true; } retropt_bool(opts, OPT_LOWPORT, &xfd->para.socket.ip.lowport); #endif /* WITH_TCP || WITH_UDP */ applyopts(xfd->fd, opts, PH_PRELISTEN); retropt_int(opts, OPT_BACKLOG, &backlog); if (Listen(xfd->fd, backlog) < 0) { Error3("listen(%d, %d): %s", xfd->fd, backlog, strerror(errno)); return STAT_RETRYLATER; } if (xioopts.logopt == 'm') { Info("starting accept loop, switching to syslog"); diag_set('y', xioopts.syslogfac); xioopts.logopt = 'y'; } else { Info("starting accept loop"); } while (true) { /* but we only loop if fork option is set */ char peername[256]; char sockname[256]; int ps; /* peer socket */ pa = &_peername; la = &_sockname; salen = sizeof(struct sockaddr); do { /*? int level = E_ERROR;*/ Notice1("listening on %s", sockaddr_info(us, uslen, lisname, sizeof(lisname))); ps = Accept(xfd->fd, (struct sockaddr *)&sa, &salen); if (ps >= 0) { /*0 Info4("accept(%d, %p, {"F_Zu"}) -> %d", xfd->fd, &sa, salen, ps);*/ break; /* success, break out of loop */ } if (errno == EINTR) { continue; } if (errno == ECONNABORTED) { Notice4("accept(%d, %p, {"F_socklen"}): %s", xfd->fd, &sa, salen, strerror(errno)); continue; } Msg4(level, "accept(%d, %p, {"F_socklen"}): %s", xfd->fd, &sa, salen, strerror(errno)); Close(xfd->fd); return STAT_RETRYLATER; } while (true); applyopts_cloexec(ps, opts); if (Getpeername(ps, &pa->soa, &pas) < 0) { Warn4("getpeername(%d, %p, {"F_socklen"}): %s", ps, pa, pas, strerror(errno)); pa = NULL; } if (Getsockname(ps, &la->soa, &las) < 0) { Warn4("getsockname(%d, %p, {"F_socklen"}): %s", ps, la, las, strerror(errno)); la = NULL; } Notice2("accepting connection from %s on %s", pa? sockaddr_info(&pa->soa, pas, peername, sizeof(peername)):"NULL", la? sockaddr_info(&la->soa, las, sockname, sizeof(sockname)):"NULL"); if (pa != NULL && la != NULL && xiocheckpeer(xfd, pa, la) < 0) { if (Shutdown(ps, 2) < 0) { Info2("shutdown(%d, 2): %s", ps, strerror(errno)); } Close(ps); continue; } if (pa != NULL) Info1("permitting connection from %s", sockaddr_info((struct sockaddr *)pa, pas, infobuff, sizeof(infobuff))); if (dofork) { pid_t pid; /* mostly int; only used with fork */ sigset_t mask_sigchld; /* we must prevent that the current packet triggers another fork; therefore we wait for a signal from the recent child: USR1 indicates that is has consumed the last packet; CHLD means it has terminated */ /* block SIGCHLD and SIGUSR1 until parent is ready to react */ sigemptyset(&mask_sigchld); sigaddset(&mask_sigchld, SIGCHLD); Sigprocmask(SIG_BLOCK, &mask_sigchld, NULL); if ((pid = xio_fork(false, level==E_ERROR?level:E_WARN)) < 0) { Close(xfd->fd); Sigprocmask(SIG_UNBLOCK, &mask_sigchld, NULL); return STAT_RETRYLATER; } if (pid == 0) { /* child */ pid_t cpid = Getpid(); Sigprocmask(SIG_UNBLOCK, &mask_sigchld, NULL); Info1("just born: child process "F_pid, cpid); xiosetenvulong("PID", cpid, 1); if (Close(xfd->fd) < 0) { Info2("close(%d): %s", xfd->fd, strerror(errno)); } xfd->fd = ps; #if WITH_RETRY /* !? */ xfd->forever = false; xfd->retry = 0; level = E_ERROR; #endif /* WITH_RETRY */ break; } /* server: continue loop with listen */ /* shutdown() closes the socket even for the child process, but close() does what we want */ if (Close(ps) < 0) { Info2("close(%d): %s", ps, strerror(errno)); } /* now we are ready to handle signals */ Sigprocmask(SIG_UNBLOCK, &mask_sigchld, NULL); while (maxchildren) { if (num_child < maxchildren) break; Notice("maxchildren are active, waiting"); /* UINT_MAX would even be nicer, but Openindiana works only with 31 bits */ while (!Sleep(INT_MAX)) ; /* any signal lets us continue */ } Info("still listening"); } else { if (Close(xfd->fd) < 0) { Info2("close(%d): %s", xfd->fd, strerror(errno)); } xfd->fd = ps; break; } } applyopts(xfd->fd, opts, PH_FD); applyopts(xfd->fd, opts, PH_PASTSOCKET); applyopts(xfd->fd, opts, PH_CONNECTED); if ((result = _xio_openlate(xfd, opts)) < 0) return result; /* set the env vars describing the local and remote sockets */ if (la != NULL) xiosetsockaddrenv("SOCK", la, las, proto); if (pa != NULL) xiosetsockaddrenv("PEER", pa, pas, proto); return 0; }
int main(int argc, char *argv[]) { unsigned int portnumber; unsigned int maxslidewindowsize; interface_info_t ii[MAX_INTERFACE_INFO] = {0,}; size_t interface_info_len; fd_set rset, mainset; int maxfdp1, i, n, mysockfd, is_local, pid, client_sockfd, temp_port, new_client_conn, table_count = 0; const int do_not_route = 1, on = 1; char str[INET_ADDRSTRLEN], msg[MAXLINE]; struct sockaddr_in cliaddr, my_recv_addr, my_recv_netmask, cli_conn; table_t table[1000]; socklen_t len = sizeof(cliaddr); char filename[4096] = {0,}; bzero(&cliaddr, sizeof(cliaddr)); bzero(&cli_conn, sizeof(cli_conn)); bzero(&my_recv_addr, sizeof(my_recv_addr)); if (readargsfromfile(&portnumber, &maxslidewindowsize) == -1) { err_quit("Read/parse error from server.in file"); return -1; } printf("port num: %d\nmaxslidewinsize:%d\n\n", portnumber, maxslidewindowsize); build_inferface_info(ii, &interface_info_len, 1, portnumber); print_interface_info(ii, interface_info_len); build_fd_set(&mainset, ii, interface_info_len, &maxfdp1); for ( ; ; ) { rset = mainset; Select(maxfdp1, &rset, NULL, NULL, NULL); for (i = 0; i < interface_info_len; i++) { if (FD_ISSET(ii[i].sockfd, &rset)) { printf("Data recieved on %s\n", Sock_ntop((SA*) (ii[i].ip), sizeof(*(ii[i].ip)))); mysockfd = ii[i].sockfd; my_recv_addr = *(ii[i].ip); my_recv_netmask = *(ii[i].netmask); n = Recvfrom(ii[i].sockfd, msg, MAXLINE, 0, (SA*) &cliaddr, &len); printf("Data recieved from: %s\n", Sock_ntop((SA*) &cliaddr, len)); memcpy(filename, msg, 4096); if (strchr(filename, '\n')) *strchr(filename, '\n') = '\0'; printf("Data(Filename):%s\n", msg); if (checktable(cliaddr, table_count, table) < 0 ) { printf("Same <ip and port> tried to conected again, not creating new child.\n"); continue; } if ((pid = Fork()) == 0) { // Child // CLose all other sockets. for (i = 0; i < interface_info_len; i++) if (ii[i].sockfd != mysockfd) close(ii[i].sockfd); // Find out if client is loopback or local or not. is_local = find_if_client_local(my_recv_addr, cliaddr, ii, interface_info_len, my_recv_netmask); if (is_local < 3) printf("Client host is local\n"); else printf("Client host is not local\n"); // Create UDP socket to handle file transfer with this client."connection socket" client_sockfd = Socket(AF_INET, SOCK_DGRAM, 0); if (is_local < 3) Setsockopt(client_sockfd, SOL_SOCKET, SO_DONTROUTE, &do_not_route, sizeof(do_not_route)); Setsockopt(client_sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); cli_conn.sin_addr = my_recv_addr.sin_addr; cli_conn.sin_family = AF_INET; cli_conn.sin_port = htons(0); Bind(client_sockfd, (SA *) &cli_conn, sizeof(cli_conn)); len = sizeof(cli_conn); Getsockname(client_sockfd, (SA*) &cli_conn, &len); printf("\nConnection socket bound, protocol Address:%s\n", Sock_ntop((SA*) &cli_conn, len)); Connect(client_sockfd, (SA*) &cliaddr, sizeof(cliaddr)); len = sizeof(cliaddr); Getpeername(client_sockfd, (SA*) &cliaddr, &len); printf("\nServer child connected to client, protocol Address:%s\n", Sock_ntop((SA*) &cliaddr, len)); temp_port = ntohs(cli_conn.sin_port); send_buffer_t buf; sprintf(buf.payload, "%d", temp_port); buf.hdr.cntrl = 1; long long seq = -1; static void sig_alrm(int signo); Signal(SIGALRM, sig_alrm); Sendto(mysockfd, &buf, sizeof(buf), 0,(SA*) &cliaddr, len); printf("New port sent.\n"); alarm(5); if (sigsetjmp(jmpbuf, 1) != 0) { printf ("Didn't receive ack for port number transfer. Resending.\n"); Sendto(mysockfd, &buf, sizeof(buf), 0,(SA*) &cliaddr, len); Write(client_sockfd, &buf, sizeof(buf)); alarm (5); } send_buffer_t rb; do { memset(&rb, 0, sizeof(rb)); n = read(client_sockfd, &rb, sizeof(rb)); } while (rb.hdr.cntrl == 0); printf("Msg (ACK) on new port\n"); close(mysockfd); alarm(0); memset(&buf, 0, sizeof(buf)); buf.hdr.sft = 1; Write(client_sockfd, &buf, sizeof(buf)); if (send_file(filename, client_sockfd, maxslidewindowsize)) printf("Failed to send file\n"); table[table_count].is_conn = 0; exit(0);// exit child } else if (pid > 0) { table[table_count].ip = cliaddr; table[table_count].is_conn = 1; table_count++; } else { err_sys("Creating child failed: "); } } } } return 0; }
/* Cliente Aplicacao simples de cliente tcp que se conecta num IP e PORTA passados por parametro, envia um comando ao servidor e escreve na saida padrao o retorno */ int main(int argc, char **argv) { // Declaracao de variaveis int sockfd; char buf[MAXDATASIZE + 1], error[MAXDATASIZE + 1]; char server[MAXDATASIZE + 1], server_reply[MAXDATASIZE + 1]; struct sockaddr_in servaddr; // Checa a presenca do parametro de IP e Porta // caso ausente, fecha o programa if (argc != 3) { strcpy(error,"uso: "); strcat(error,argv[0]); strcat(error," <IPaddress> <Port>"); perror(error); exit(1); } // Cria um socket sockfd = Socket(AF_INET, SOCK_STREAM, 0); // Limpa o que estiver no ponteiro do socket que representa o servidor // Seta o socket do servidor como IPv4 e seta a porta de conexao para a porta da aplicacao. bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(atoi(argv[2])); // Converte o IP recebido na entrada para a forma binária da struct InetPton(AF_INET, argv[1], servaddr); // Conecta o socket local com o socket servidor Connect(sockfd, servaddr); // Escrever IP e porta do servidor na saida padrao printf("Server: IP %s - Port %d\n", argv[1], atoi(argv[2])); // Coletar informacoes sobre o socket com o servidor servaddr = Getsockname(sockfd, servaddr); // Converter informacao do IP de binario para string // armazenar o resultado no buffer InetNtop(AF_INET, server, servaddr); // Escrever IP e porta do cliente no socket na saida padrao printf("Client: IP %s - Port %d\n", server, ntohs(servaddr.sin_port)); // lê uma cadeia de caracteres do teclado printf("Digite um comando:\n"); fgets(buf, MAXDATASIZE, stdin); // Imprime a linha de comando digitada pelo usuario printf("Linha de comando digitada: %s", buf); // envia os dados lidos ao servidor Write(sockfd , buf); // le os dados enviados pelo servidor Read(sockfd, server_reply); // Imprime a linha de comando devolvida pelo servidor printf("Linha de comando recebida: %s\n", server_reply); exit(0); }
/* perform socks4 client dialog on existing FD. Called within fork/retry loop, after connect() */ int _xioopen_socks4_connect(struct single *xfd, struct socks4 *sockhead, size_t headlen, int level) { ssize_t bytes; int result; unsigned char buff[SIZEOF_STRUCT_SOCKS4]; struct socks4 *replyhead = (struct socks4 *)buff; char *destdomname = NULL; /* send socks header (target addr+port, +auth) */ #if WITH_MSGLEVEL <= E_INFO if (ntohl(sockhead->dest) <= 0x000000ff) { destdomname = strchr(sockhead->userid, '\0')+1; } Info11("sending socks4%s request VN=%d DC=%d DSTPORT=%d DSTIP=%d.%d.%d.%d USERID=%s%s%s", destdomname?"a":"", sockhead->version, sockhead->action, ntohs(sockhead->port), ((unsigned char *)&sockhead->dest)[0], ((unsigned char *)&sockhead->dest)[1], ((unsigned char *)&sockhead->dest)[2], ((unsigned char *)&sockhead->dest)[3], sockhead->userid, destdomname?" DESTNAME=":"", destdomname?destdomname:""); #endif /* WITH_MSGLEVEL <= E_INFO */ #if WITH_MSGLEVEL <= E_DEBUG { char *msgbuff; if ((msgbuff = Malloc(3*headlen)) != NULL) { xiohexdump((const unsigned char *)sockhead, headlen, msgbuff); Debug1("sending socks4(a) request data %s", msgbuff); } } #endif /* WITH_MSGLEVEL <= E_DEBUG */ if (writefull(xfd->fd, sockhead, headlen) < 0) { Msg4(level, "write(%d, %p, "F_Zu"): %s", xfd->fd, sockhead, headlen, strerror(errno)); if (Close(xfd->fd) < 0) { Info2("close(%d): %s", xfd->fd, strerror(errno)); } return STAT_RETRYLATER; /* retry complete open cycle */ } bytes = 0; Info("waiting for socks reply"); while (bytes >= 0) { /* loop over answer chunks until complete or error */ /* receive socks answer */ do { result = Read(xfd->fd, buff+bytes, SIZEOF_STRUCT_SOCKS4-bytes); } while (result < 0 && errno == EINTR); if (result < 0) { Msg4(level, "read(%d, %p, "F_Zu"): %s", xfd->fd, buff+bytes, SIZEOF_STRUCT_SOCKS4-bytes, strerror(errno)); if (Close(xfd->fd) < 0) { Info2("close(%d): %s", xfd->fd, strerror(errno)); } } if (result == 0) { Msg(level, "read(): EOF during read of socks reply, peer might not be a socks4 server"); if (Close(xfd->fd) < 0) { Info2("close(%d): %s", xfd->fd, strerror(errno)); } return STAT_RETRYLATER; } #if WITH_MSGLEVEL <= E_DEBUG { char msgbuff[3*SIZEOF_STRUCT_SOCKS4]; * xiohexdump((const unsigned char *)replyhead+bytes, result, msgbuff) = '\0'; Debug2("received socks4 reply data (offset "F_Zd"): %s", bytes, msgbuff); } #endif /* WITH_MSGLEVEL <= E_DEBUG */ bytes += result; if (bytes == SIZEOF_STRUCT_SOCKS4) { Debug1("received all "F_Zd" bytes", bytes); break; } Debug2("received %d bytes, waiting for "F_Zu" more bytes", result, SIZEOF_STRUCT_SOCKS4-bytes); } if (result <= 0) { /* we had a problem while reading socks answer */ return STAT_RETRYLATER; /* retry complete open cycle */ } Info7("received socks reply VN=%u CD=%u DSTPORT=%u DSTIP=%u.%u.%u.%u", replyhead->version, replyhead->action, ntohs(replyhead->port), ((uint8_t *)&replyhead->dest)[0], ((uint8_t *)&replyhead->dest)[1], ((uint8_t *)&replyhead->dest)[2], ((uint8_t *)&replyhead->dest)[3]); if (replyhead->version != 0) { Warn1("socks: reply code version is not 0 (%d)", replyhead->version); } switch (replyhead->action) { case SOCKS_CD_GRANTED: /* Notice("socks: connect request succeeded"); */ #if 0 if (Getsockname(xfd->fd, (struct sockaddr *)&us, &uslen) < 0) { Warn4("getsockname(%d, %p, {%d}): %s", xfd->fd, &us, uslen, strerror(errno)); } Notice1("successfully connected from %s via socks4", sockaddr_info((struct sockaddr *)&us, infobuff, sizeof(infobuff))); #else Notice("successfully connected via socks4"); #endif break; case SOCKS_CD_FAILED: Msg(level, "socks: connect request rejected or failed"); return STAT_RETRYLATER; case SOCKS_CD_NOIDENT: Msg(level, "socks: ident refused by client"); return STAT_RETRYLATER; case SOCKS_CD_IDENTFAILED: Msg(level, "socks: ident failed"); return STAT_RETRYLATER; default: Msg1(level, "socks: undefined status %u", replyhead->action); } return STAT_OK; }
int main(int argc, char *argv[]) { int c, lopt=0; char *ptr, localname[1024], *localport; struct addrinfo *aip; /* end main1 */ /* include main2 */ opterr = 0; /* don't want getopt() writing to stderr */ while ( (c = getopt(argc, argv, "0i:l:v")) != -1) { switch (c) { case '0': zerosum = 1; break; case 'i': device = optarg; /* pcap device */ break; case 'l': /* local IP address and port #: a.b.c.d.p */ if ( (ptr = strrchr(optarg, '.')) == NULL) usage("invalid -l option"); *ptr++ = 0; /* null replaces final period */ localport = ptr; /* service name or port number */ strncpy(localname, optarg, sizeof(localname)); lopt = 1; break; case 'v': verbose = 1; break; case '?': usage("unrecognized option"); } } /* end main2 */ /* include main3 */ if (optind != argc-2) usage("missing <host> and/or <serv>"); /* 4convert destination name and service */ aip = Host_serv(argv[optind], argv[optind+1], AF_INET, SOCK_DGRAM); dest = aip->ai_addr; /* don't freeaddrinfo() */ destlen = aip->ai_addrlen; /* * Need local IP address for source IP address for UDP datagrams. * Can't specify 0 and let IP choose, as we need to know it for * the pseudoheader to calculate the UDP checksum. * If -l option supplied, then use those values; otherwise, * connect a UDP socket to the destination to determine the right * source address. */ if (lopt) { /* 4convert local name and service */ aip = Host_serv(localname, localport, AF_INET, SOCK_DGRAM); local = aip->ai_addr; /* don't freeaddrinfo() */ locallen = aip->ai_addrlen; } else { int s; s = Socket(AF_INET, SOCK_DGRAM, 0); Connect(s, dest, destlen); /* kernel chooses correct local address for dest */ locallen = sizeof(locallookup); local = (struct sockaddr *)&locallookup; Getsockname(s, local, &locallen); if (locallookup.sin_addr.s_addr == htonl(INADDR_ANY)) err_quit("Can't determine local address - use -l\n"); close(s); } open_output(); /* open output, either raw socket or libnet */ open_pcap(); /* open packet capture device */ setuid(getuid()); /* don't need superuser privileges anymore */ Signal(SIGTERM, cleanup); Signal(SIGINT, cleanup); Signal(SIGHUP, cleanup); test_udp(); cleanup(0); }
void socket_rcvFile() { struct sockaddr_in server_sockaddr, client_sockaddr; int sin_size, recvbytes, sendbytes; int sockfd, client_fd, desc_ready; sin_size=sizeof(client_sockaddr); /*Data structure to handle timeout*/ struct timeval before, timer, *tvptr; struct timezone tzp; /* Data structure for the select I/O */ fd_set ready_set, test_set; int maxfd, nready, nbytes; /* create socket */ sockfd = Socket(AF_INET,SOCK_STREAM,0); /* set parameters for sockaddr_in */ server_sockaddr.sin_family = AF_INET; server_sockaddr.sin_port = htons(0); //0, assign port automatically in 1024 ~ 65535 server_sockaddr.sin_addr.s_addr = INADDR_ANY; //0, got local IP automatically bzero(&(server_sockaddr.sin_zero), 8); int i = 1;//enable reuse the combination of local address and socket setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i)); Bind(sockfd, server_sockaddr); int port; char str[6], hostname[1024], addrstr[100]; getaddr(hostname, addrstr); //get hostname and ip port = Getsockname(sockfd, server_sockaddr, sin_size); /* Get the port number assigned*/ sprintf(str, "%d", port); // int to str FILE * f; char filename[80]; strcpy(filename, "../."); strcat(filename, addrstr); strcat(filename, "\0"); if(f = fopen(filename, "w")) { fputs(str,f); fclose(f); } else printf("ERROR: Writing port to file\n"); Listen(sockfd, 1024); printf("STARTUP: Server is setup on port %d\n", port); if(fork() == 0) { while(1) { client_fd = Accept(sockfd, client_sockaddr, sin_size); /* Receive from the remote side */ int cont = 1; while(cont == 1) { Packet recieved; Recv(client_fd,&recieved,sizeof(recieved),0); printf("socket_sendFile: got packet from %s with type %s\n", recieved.RouterID, recieved.PacketType); struct packet pkt = convertCharToPacket(recieved); if(lsrp_incomingmessage(pkt) == 0) { Packet ack = convertPacketToChar(lsrp_createACK(pkt)); Send(client_fd, &ack, sizeof(ack),0); printf("socket_sendFile: send ack from %s with type %s\n", ack.RouterID, ack.PacketType); //close(client_fd); // do not close client socket //cont = 0; } } } } }