static void tryconnect(struct silly_socket *ss, struct cmdpacket *cmd) { int err; int fd; struct sockaddr addr; int sid = cmd->u.connect.sid; int port = cmd->u.connect.port; int bport = cmd->u.connect.bport; const char *ip = cmd->u.connect.ip; const char *bip = cmd->u.connect.bip; struct socket *s = &ss->socketpool[HASH(sid)]; assert(s->sid == sid); assert(s->type == STYPE_ALLOCED); tosockaddr(&addr, ip, port); fd = socket(AF_INET, SOCK_STREAM, 0); if (fd >= 0) err = bindfd(fd, bip, bport); if (fd < 0 || err < 0) { const char *fmt = "[socket] bind %s:%d, errno:%d\n"; fprintf(stderr, fmt, bip, bport, errno); if (fd >= 0) close(fd); report_close(ss, s, errno); freesocket(ss, s); return ; } nonblock(fd); keepalive(fd); nodelay(fd); err = connect(fd, &addr, sizeof(addr)); if (err == -1 && errno != EINPROGRESS) { //error const char *fmt = "[socket] tryconnect %s:%d,errno:%d\n"; fprintf(stderr, fmt, ip, port, errno); close(fd); report_close(ss, s, errno); freesocket(ss, s); return ; } else if (err == 0) { //connect s = newsocket(ss, s, fd, STYPE_SOCKET, report_close); if (s != NULL) report_connected(ss, s); return ; } else { //block s = newsocket(ss, s, fd, STYPE_CONNECTING, report_close); if (s != NULL) sp_write_enable(ss->spfd, s->fd, s, 1); } return ; }
static void report_accept(struct silly_socket *ss, struct socket *listen) { const char *str; struct socket *s; struct sockaddr_in addr; struct silly_message_socket *sa; char buff[INET_ADDRSTRLEN]; assert(ADDRLEN >= INET_ADDRSTRLEN + 8); socklen_t len = sizeof(struct sockaddr); int fd = accept(listen->fd, (struct sockaddr *)&addr, &len); if (fd < 0) return ; sa = silly_malloc(sizeof(*sa) + ADDRLEN); sa->data = (uint8_t *)(sa + 1); sa->type = SILLY_SACCEPT; str = inet_ntop(addr.sin_family, &addr.sin_addr, buff, sizeof(buff)); snprintf((char *)sa->data, ADDRLEN, "%s:%d", str, ntohs(addr.sin_port)); nonblock(fd); keepalive(fd); nodelay(fd); s = newsocket(ss, NULL, fd, STYPE_SOCKET, NULL); if (s == NULL) return; sa->sid = s->sid; sa->ud = listen->sid; silly_worker_push(tocommon(sa)); return ; }
static void tryudpconnect(struct silly_socket *ss, struct cmdpacket *cmd) { int sid = cmd->u.udpconnect.sid; struct socket *s = &ss->socketpool[HASH(sid)]; assert(s->sid == sid); assert(s->type == STYPE_ALLOCED); s = newsocket(ss, s, cmd->u.udpconnect.fd, STYPE_SOCKET, report_close); if (s != NULL) report_connected(ss, s); return ; }
void TCPSocket::cleanup() { newsocket(socket(DOMAIN, TYPE, PROTOCOL)); }
static void initsockets(const char *bindaddr[MAXSOCK], int nba, int UNUSED family) { int i, x; char *host, *serv; const char *ba; #ifdef NO_IPv6 struct sockaddr_in sin; ip4addr_t sinaddr; int port; struct servent *se; struct hostent *he; memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; if (!(se = getservbyname("domain", "udp"))) port = htons(DNS_PORT); else port = se->s_port; #else struct addrinfo hints, *aires, *ai; memset(&hints, 0, sizeof(hints)); hints.ai_family = family; hints.ai_socktype = SOCK_DGRAM; hints.ai_flags = AI_PASSIVE; #endif for (i = 0; i < nba; ++i) { ba = bindaddr[i]; host = estrdup(ba); serv = strchr(host, '/'); if (serv) { *serv++ = '\0'; if (!*host) error(0, "missing host part in bind address `%.60s'", ba); } #ifdef NO_IPv6 if (!serv || !*serv) sin.sin_port = port; else if ((x = satoi(serv)) > 0 && x <= 0xffff) sin.sin_port = htons(x); else if (!(se = getservbyname(serv, "udp"))) error(0, "unknown service in `%.60s'", ba); else sin.sin_port = se->s_port; if (ip4addr(host, &sinaddr, NULL) > 0) { sin.sin_addr.s_addr = htonl(sinaddr); newsocket(&sin); } else if (!(he = gethostbyname(host)) || he->h_addrtype != AF_INET || he->h_length != 4 || !he->h_addr_list[0]) error(0, "unknown host in `%.60s'", ba); else { for(x = 0; he->h_addr_list[x]; ++x) { memcpy(&sin.sin_addr, he->h_addr_list[x], 4); newsocket(&sin); } } #else if (!serv || !*serv) serv = "domain"; x = getaddrinfo(host, serv, &hints, &aires); if (x != 0) error(0, "%.60s: %s", ba, gai_strerror(x)); for(ai = aires, x = 0; ai; ai = ai->ai_next) if (newsocket(ai)) ++x; if (!x) error(0, "%.60s: no available protocols", ba); freeaddrinfo(aires); #endif free(host); } endservent(); endhostent(); for (i = 0; i < numsock; ++i) { x = 65536; do if (setsockopt(sock[i], SOL_SOCKET, SO_RCVBUF, (void*)&x, sizeof x) == 0) break; while ((x -= (x >> 5)) >= 1024); } }
BCPLWORD callc(BCPLWORD *args, BCPLWORD *g) { int rc = 0; BCPLWORD fno = args[0]; //printf("\nCallc: fno = %d\n", fno); switch(fno) { default: return -1; case c_name2ipaddr: // name => ipaddr (host format) b2c_str(args[1], namebuf); //printf("Callc c_name2ipaddr: args[1]=%d %s\n", // args[1], namebuf); return name2ipaddr(namebuf); case c_name2port: // name => port (host format) b2c_str(args[1], namebuf); //printf("callc c_name2port: %s\n", namebuf); return name2port(namebuf); case c_newsocket: // Allocate a new socket return newsocket(); case c_reuseaddr: // Reuse address return reuseaddr((int)args[1], (int)args[2]); case c_setsndbufsz: // Set the send buffer size return setsndbufsz((int)args[1], (int)args[2]); case c_setrcvbufsz: // Set the recv buffer size return setrcvbufsz((int)args[1], (int)args[2]); case c_tcpbind: // Bind a socket to a given ipaddr/port //printf("c_tcpbind: %d %08x %d\n", args[1], args[2], args[3]); return tcpbind((int)args[1], (int)args[2], (int)args[3]); case c_tcpconnect: // Connect a socket to a given ipaddr/port //printf("tcpconnect %d %08x %d\n", args[1], args[2], args[3]); return tcpconnect((int)args[1], (int)args[2], (int)args[3]); case c_tcplisten: // Cause a socket to listen return tcplisten((int)args[1], (int)args[2]); case c_tcpaccept: // Cause a socket to accept a connection return tcpaccept((int)args[1]); case c_tcpclose: // Close a connection //printf("tcpclose %d\n", args[1]); return close((int)args[1]); case c_fd_zero: // Clear all bits in an fd_set { //fd_set *bits = (fd_set*)&W[args[2]]; FD_ZERO((fd_set*)&W[args[1]]); return 0; } case c_fd_set: // Set a bit in an fd_set //printf("c_fd_set: args[1]=%d args[2]=%d\n", args[1], args[2]); FD_SET((int)args[1], (fd_set*)&W[args[2]]); return 0; case c_fd_isset: // Test a bit in an fd_set return FD_ISSET((int)args[1], (fd_set*)&W[args[2]]); case c_select: // Call the select function { int i, rc; int s = (int) args[1]; fd_set *rd_set = (fd_set *) &W[args[2]]; fd_set *wr_set = (fd_set *) &W[args[3]]; fd_set *er_set = (fd_set *) &W[args[4]]; struct timeval *timeval = (struct timeval *) ((args[5]==0) ? NULL : &W[args[5]]); /* //for(i=0; i<10;i++) // printf("callc: rdset bit %d = %d\n", i, FD_ISSET(i, (fd_set*)&W[args[2]])); */ //printf("callc: calling select(%d,%d,%d,%d,%d)\n", // args[1],args[2],args[3],args[4],args[5]); //if(timeval) { //printf("c_select: tv_sec = %d\n", timeval->tv_sec); //printf("c_select: tv_usec = %d\n", timeval->tv_usec); //} rc = select(s, rd_set, wr_set, er_set, timeval); if(rc==-1) perror("select returned error"); //printf("\ncallc: select => rc = %d\n", rc); //for(i=0; i<10;i++) // printf("callc: rdset bit %d = %d\n", // i, FD_ISSET(i, rd_set)); return rc; } case c_recv: // Call the recv(s, buf, len, flags) { int s = (int)args[1]; char *buf = (char*)&W[args[2]]; int len = (int)args[3]; int flags = (int)args[4]; int rc = 0; //printf("cfuncs: Calling recv(%d, %d, %d, %d)\n", // args[1], args[2], args[3], args[4]); rc = recv(s, buf, len, flags); if(rc==-1)perror("recv returned error"); //printf("cfuncs: recv returned rc=%d\n", rc); return rc; } case c_send: // Call the send(s, buf, len, flags) { int s = (int)args[1]; char *buf = (char*)&W[args[2]]; int len = (int)args[3]; int flags = (int)args[4]; int rc = 0; //printf("cfuncs: Calling send(%d, %d, %d, %d)\n", // args[1], args[2], args[3], args[4]); rc = send(s, buf, len, flags); if(rc==-1)perror("send returned error"); //printf("cfuncs: send returned rc=%d\n", rc); return rc; } case c_read: // Call the read(s, buf, len) { int s = (int)args[1]; char *buf = (char*)&W[args[2]]; int len = (int)args[3]; int rc = 0; //printf("cfuncs: Calling read(%d, %d, %d)\n", args[1], args[2], args[3]); rc = read(s, buf, len); //if(rc==-1)perror("read returned error"); //printf("cfuncs: read returned rc=%d\n", rc); return rc; } case c_write: // Call the write(s, buf, len) { int s = (int) args[1]; char *buf = (char*) &W[args[2]]; int len = (int) args[3]; int rc = 0; //printf("cfuncs: Calling write(%d, %d, %d)\n", args[1], args[2], args[3]); rc = write(s, buf, len); if(rc==-1)perror("read returned error"); //printf("cfuncs: read returned rc=%d\n", rc); return rc; } } }