int sock_close (socket_t *self) { int rc = 0; int fd = self->sfd; if (0 == fd) { return -1; } rc = shutdown(fd, SHUT_RDWR); if (rc < 0) { return sock_perror("sock_close"), rc; } rc = close(fd); if (rc < 0) { return sock_perror("sock_close"), rc; } self->sfd = 0; return rc; }
int sock_connect (socket_t *self) { int rc = connect(self->fd, (struct sockaddr *) self->addr, sizeof(struct sockaddr_in)); if (rc < 0) { return sock_perror("sock_connect"), rc; } return rc; }
int sock_bind (socket_t *self) { size_t len = sizeof(struct sockaddr_in); int rc = bind(self->fd, (struct sockaddr *) self->addr, len); if (rc < 0) { return sock_perror("sock_bind"), rc; } return rc; }
int sock_accept (socket_t *self) { socklen_t len = sizeof(struct sockaddr_in); int sfd = accept(self->fd, (struct sockaddr *) self->addr, &len); if (sfd < 0) { return sock_perror("sock_accept"), sfd; } self->sfd = sfd; return sfd; }
int sock_tcp_listen (socket_t *sock) { socket_tcp_t *self = (socket_tcp_t *) sock; int rc = listen(sock->fd, self->backlog); if (rc < 0) { return sock_perror("sock_tcp_listen"), rc; } return rc; }
int sock_read (socket_t *self, char *buf, size_t size) { int rc = 0; int len = 0; memset(buf, 0, size); len = read(self->fd, buf, size); if (len < 0) { return sock_perror("sock_read"), -1; } return len; }
int sock_shutdown (socket_t *self) { int rc = 0; if (self->sfd > 0) { rc = sock_close(self); } if (rc < 0) { return rc; } rc = shutdown(self->fd, SHUT_RDWR); if (rc < 0) { return sock_perror("sock_shutdown"), rc; } return rc; }
char * sock_recv (socket_t *self, int cont) { ssize_t size = 0; char *buf = (char *) malloc(sizeof(buf) * SOCK_BUFSIZE); int fd = self->sfd > 0 ? self->sfd : self->fd; if (NULL == buf) { return NULL; } read: size = recv(fd, buf, SOCK_BUFSIZE, 0); buf[size] = '\0'; if (size < 0) return sock_perror("sock_recv()"), free(buf), NULL; else if (0 == size && 0 != cont) goto read; return buf; }
socket_t * sock_new (int domain, int type) { socket_t *self = NULL; int fd = 0; fd = sock_raw_new(domain, type, 0); if (fd < 0) { return sock_perror("sock_new"), NULL; } self = (socket_t *) malloc(sizeof(socket_t)); self->domain = domain; self->sock_type = type; sock_init(self, fd); if (NULL == self) { return NULL; } return self; }
char * sock_recvfrom (socket_t *self) { ssize_t size = 0; char *buf = (char *) malloc(sizeof(buf) * SOCK_BUFSIZE); if (NULL == buf) { return NULL; } read: size = recvfrom( self->fd, buf, SOCK_BUFSIZE, 0, (struct sockaddr *) self->addr, (socklen_t *) sizeof(self->addr)); buf[size] = '\0'; if (size < 0) { return sock_perror("sock_recvfrom()"), free(buf), NULL; } else if (0 == size) goto read; return buf; }
/* Testing code for event_base_dump_events(). Notes that just because we have code to exercise this function, doesn't mean that *ANYTHING* about the output format is guaranteed to remain in the future. */ int main(int argc, char **argv) { #define N_EVENTS 13 int i; struct event *ev[N_EVENTS]; evutil_socket_t pair1[2]; evutil_socket_t pair2[2]; struct timeval tv_onesec = {1,0}; struct timeval tv_two5sec = {2,500*1000}; const struct timeval *tv_onesec_common; const struct timeval *tv_two5sec_common; struct event_base *base; struct timeval now; #ifdef _WIN32 WORD wVersionRequested; WSADATA wsaData; wVersionRequested = MAKEWORD(2, 2); WSAStartup(wVersionRequested, &wsaData); #endif #ifdef _WIN32 #define LOCAL_SOCKETPAIR_AF AF_INET #else #define LOCAL_SOCKETPAIR_AF AF_UNIX #endif if (evutil_make_internal_pipe_(pair1) < 0 || evutil_make_internal_pipe_(pair2) < 0) { sock_perror("evutil_make_internal_pipe_"); return 1; } if (!(base = event_base_new())) { fprintf(stderr,"Couldn't make event_base\n"); return 2; } tv_onesec_common = event_base_init_common_timeout(base, &tv_onesec); tv_two5sec_common = event_base_init_common_timeout(base, &tv_two5sec); ev[0] = event_new(base, pair1[0], EV_WRITE, callback1, NULL); ev[1] = event_new(base, pair1[1], EV_READ|EV_PERSIST, callback1, NULL); ev[2] = event_new(base, pair2[0], EV_WRITE|EV_PERSIST, callback2, NULL); ev[3] = event_new(base, pair2[1], EV_READ, callback2, NULL); /* For timers */ ev[4] = evtimer_new(base, callback1, NULL); ev[5] = evtimer_new(base, callback1, NULL); ev[6] = evtimer_new(base, callback1, NULL); ev[7] = event_new(base, -1, EV_PERSIST, callback2, NULL); ev[8] = event_new(base, -1, EV_PERSIST, callback2, NULL); ev[9] = event_new(base, -1, EV_PERSIST, callback2, NULL); /* To activate */ ev[10] = event_new(base, -1, 0, callback1, NULL); ev[11] = event_new(base, -1, 0, callback2, NULL); /* Signals */ ev[12] = evsignal_new(base, SIGINT, callback2, NULL); event_add(ev[0], NULL); event_add(ev[1], &tv_onesec); event_add(ev[2], tv_onesec_common); event_add(ev[3], tv_two5sec_common); event_add(ev[4], tv_onesec_common); event_add(ev[5], tv_onesec_common); event_add(ev[6], &tv_onesec); event_add(ev[7], tv_two5sec_common); event_add(ev[8], tv_onesec_common); event_add(ev[9], &tv_two5sec); event_active(ev[10], EV_READ, 1); event_active(ev[11], EV_READ|EV_WRITE|EV_TIMEOUT, 1); event_active(ev[1], EV_READ, 1); event_add(ev[12], NULL); evutil_gettimeofday(&now,NULL); puts("=====expected"); printf("Now= %ld.%06d\n",(long)now.tv_sec,(int)now.tv_usec); puts("Inserted:"); printf(" %p [fd %ld] Write\n",ev[0],(long)pair1[0]); printf(" %p [fd %ld] Read Persist Timeout=T+1\n",ev[1],(long)pair1[1]); printf(" %p [fd %ld] Write Persist Timeout=T+1\n",ev[2],(long)pair2[0]); printf(" %p [fd %ld] Read Timeout=T+2.5\n",ev[3],(long)pair2[1]); printf(" %p [fd -1] Timeout=T+1\n",ev[4]); printf(" %p [fd -1] Timeout=T+1\n",ev[5]); printf(" %p [fd -1] Timeout=T+1\n",ev[6]); printf(" %p [fd -1] Persist Timeout=T+2.5\n",ev[7]); printf(" %p [fd -1] Persist Timeout=T+1\n",ev[8]); printf(" %p [fd -1] Persist Timeout=T+2.5\n",ev[9]); printf(" %p [sig %d] Signal Persist\n", ev[12], (int)SIGINT); puts("Active:"); printf(" %p [fd -1, priority=0] Read active\n", ev[10]); printf(" %p [fd -1, priority=0] Read Write Timeout active\n", ev[11]); printf(" %p [fd %ld, priority=0] Read active\n", ev[1], (long)pair1[1]); puts("======received"); event_base_dump_events(base, stdout); for (i = 0; i < N_EVENTS; ++i) { event_free(ev[i]); } event_base_free(base); return 0; }
int main() { auto int if_status; printf("Multiple Interface Echo Test\n"); usage(); printf("\nPress any key to proceed.\n"); while (!kbhit()); getchar(); printf("Initializing TCP/IP stack...\n"); for (i = 0; i < IF_MAX; i++) ifconfig(i, IFG_IPADDR, oldip+i, #ifdef USE_IF_CALLBACK IFS_IF_CALLBACK, updowncb, #endif IFS_END); sock_init(); // Wait for the interface to come up while (IF_COMING_UP == (if_status = ifpending(IF_DEFAULT)) || IF_COMING_DOWN == if_status) { tcp_tick(NULL); } printf("...done.\n"); memset(state, 0, sizeof(state)); socknum = -1; seq = 1; ping_ip = 0; act_ip = 0; asock = s + (NUM_SOCKS - 1); astate = state + (NUM_SOCKS - 1); *astate = STATE_DONT_USE; if(!udp_extopen(&usock, IF_ANY, ECHO_PORT, -1L, 0, echo_handler, 0, 0)) { printf("udp_extopen failed!\n"); exit(0); } for (;;) { socknum++; if (socknum == NUM_SOCKS) socknum = 0; tcp_tick(NULL); if (state[socknum] > STATE_CLOSED && !sock_alive(s+socknum)) { if (socknum == NUM_LISTEN_SOCKS) { printf("Active socket closed\n"); state[socknum] = STATE_DONT_USE; } else { printf("Socket %d closed\n", socknum); state[socknum] = STATE_CLOSED; } sock_perror(s+socknum, NULL); } for (i = 0; i < IF_MAX; i++) { ifconfig(i, IFG_IPADDR, &ip, IFS_END); if (oldip[i] != ip) { printf("IPaddr on i/f %d changed from %08lx to %08lx\n", i, oldip[i], ip); oldip[i] = ip; ifconfig(i, IFS_ICMP_CONFIG_RESET, IFS_END); } } if (kbhit()) { kb = getchar(); if (kb == '?') usage(); else if (kb == 'i') ip_print_ifs(); else if (kb == 'r') router_printall(); else if (kb == 'c') arpcache_printall(); else if (kb == 'p') { printf("Press an interface number [TCP/IP now blocked]\n"); while (!kbhit()); kb = getchar(); if (isdigit(kb)) { ifconfig(kb - '0', IFG_ROUTER_DEFAULT, &ping_ip, IFS_END); if (ping_ip) { printf("Pinging router %08lX...\n", ping_ip); _send_ping(ping_ip, seq++, 1, IPTOS_DEFAULT, &ping_id); } else printf("No router for interface %d\n", kb - '0'); } else printf("No interface selected.\n"); } else if (kb == 'a') { if (act_ip && *astate != STATE_DONT_USE) { printf("Closing active connection to %s...\n", inet_ntoa(buf, act_ip)); sock_close(asock); while (tcp_tick(asock)); } *astate = STATE_DONT_USE; printf("Enter a host name or IP address [TCP/IP now blocked]\n"); gets(buf); printf("Resolving...\n"); act_ip = resolve(buf); if (act_ip) { printf("Enter a port number to connect to (0-65535)\n"); gets(buf); aport = (word)atol(buf); printf("Opening to %s:%u...\n", inet_ntoa(buf, act_ip), aport); *astate = STATE_ACTOPEN; } else printf("Could not resolve %s to IP address.\n", buf); } else if (isdigit(kb)) { // Toggle interface status kb -= '0'; if (!(1u<<kb & IF_SET)) { printf("Not a valid interface\n"); continue; } if (ifstatus(kb)) { printf("Bringing interface %d down...\n", kb); ifconfig(kb, IFS_DOWN, IFS_END); } else { printf("Bringing interface %d up...\n", kb); ifconfig(kb, IFS_UP, IFS_END); } } } if (ping_ip) { if (_chk_ping(ping_ip , &ping_id) != 0xffffffffL) { printf("Got ping response from %08lX\n", ping_ip); ping_ip = 0; } } switch (state[socknum]) { case STATE_CLOSED: if (!tcp_extlisten(s + socknum, IF_ANY, ECHO_PORT, 0, 0, t_handler, 0, 0, 0)) { printf("Listen failed - socket %d\n", socknum); state[socknum] = STATE_DONT_USE; break; } printf("Listening on socket %d...\n", socknum); state[socknum] = STATE_LISTEN; break; case STATE_ACTOPEN: if (!tcp_extopen(s + socknum, IF_ANY, 0, act_ip, aport, t_handler, 0, 0)) { printf("Active open failed\n"); state[socknum] = STATE_DONT_USE; break; } state[socknum] = STATE_LISTEN; break; case STATE_LISTEN: if (sock_established(s + socknum)) { printf("Connection %d estab.\n", socknum); state[socknum] = STATE_ESTAB; } break; case STATE_ESTAB: if ((rb = sock_fastread(s + socknum, buf, sizeof(buf))) > 0) { sock_fastwrite(s + socknum, buf, rb); if (!strncmp(buf, "quit", 4)) { printf("Peer on socket %d requests close\n", socknum); sock_close(s + socknum); state[socknum] = STATE_CLOSING; } } else if (rb < 0) { printf("Connection %d closed by peer.\n", socknum); sock_close(s + socknum); state[socknum] = STATE_CLOSING; } break; default: break; } } }