static void sp_socksrv_notify(Spfd *spfd, void *aux) { int csock; Spsrv *srv; Spconn *conn; Socksrv *ss; struct sockaddr_in caddr; socklen_t caddrlen; char buf[64]; srv = aux; ss = srv->srvaux; if (!spfd_can_read(spfd)) return; spfd_read(spfd, buf, 0); caddrlen = sizeof(caddr); csock = accept(ss->sock, (struct sockaddr *) &caddr, &caddrlen); if (csock<0) { if (!ss->shutdown) return; close(ss->sock); if (sp_socksrv_connect(ss) < 0) fprintf(stderr, "error while reconnecting: %d\n", errno); return; } fcntl(csock, F_SETFD, FD_CLOEXEC); snprintf(buf, sizeof(buf), "%s!%d", inet_ntoa(caddr.sin_addr), ntohs(caddr.sin_port)); if (!(conn = sp_conn_create(srv, strdup(buf), csock, csock))) close(csock); }
Spconn* sp_ethconn_create(Spsrv *srv, int fd) { Spconn *conn = sp_conn_create(srv); if (!conn) return NULL; Spethconn *ethconn = sp_malloc(sizeof(*ethconn)); if (!ethconn) goto error; ethconn->fd = fd; ethconn->spfd = spfd_add(fd, sp_ethconn_notify, conn); if (!ethconn->spfd) goto error; conn->caux = ethconn; conn->shutdown = sp_ethconn_shutdown; conn->dataout = sp_ethconn_dataout; sp_srv_add_conn(srv, conn); return conn; error: free(ethconn); sp_conn_destroy(conn); return NULL; }