void on_connect(EV_P_ struct ev_io *io, int revents) { while (1) { struct sockaddr_in client_addr; socklen_t len = sizeof (struct sockaddr_in); int client_sock = accept(io->fd, (struct sockaddr *) &client_addr, &len); if (client_sock >= 0) { if (set_nonblock(client_sock) == -1) { shutdown_printerr(client_sock, "can't set the socket mode O_NONBLOCK for client\n"); return; } if (set_linger(client_sock) == -1) { shutdown_printerr(client_sock, "can't set SO_LINGER sock option for client\n"); return; } if (set_keepalive(client_sock) == -1) { shutdown_printerr(client_sock, "can't set SO_KEEPALIVE sock option for client\n"); return; } server_ctx_t *srv_ctx = (server_ctx_t *) ev_userdata(loop); client_ctx_t* cli_ctx = get_client_ctx(srv_ctx); cli_ctx->io.ctx = cli_ctx; cli_ctx->connected_at = time(NULL); uuid_generate(cli_ctx->uuid); memcpy(&cli_ctx->client_addr, &client_addr, sizeof (struct sockaddr_in)); ev_io_init((ev_io *) & cli_ctx->io, client_read_write, client_sock, EV_READ); ev_io_start(loop, (ev_io *) & cli_ctx->io); char time_buff[32]; strftime(time_buff, sizeof (time_buff), "%Y-%m-%d %H:%M:%S %Z", localtime(&cli_ctx->connected_at)); char *addr = inet_ntoa(cli_ctx->client_addr.sin_addr); char uuid_buff[37]; uuid_unparse_lower(cli_ctx->uuid, (char *) &uuid_buff); printf("client accepted %s:%hu %s at %s\n", addr, client_addr.sin_port, &uuid_buff, &time_buff); char *welcome_msg = server_welcome(srv_ctx, cli_ctx); send_message(loop, cli_ctx->uuid, welcome_msg, strlen(welcome_msg)); free(welcome_msg); char *new_client_msg = server_client_connected(cli_ctx); for (ssize_t i = 0; i < srv_ctx->clients_count; i++) { if (uuid_compare(srv_ctx->clients[i]->uuid, cli_ctx->uuid) != 0) { send_message(loop, srv_ctx->clients[i]->uuid, new_client_msg, strlen(new_client_msg)); } } free(new_client_msg); } else { if (errno == EAGAIN) return; if (errno == EMFILE || errno == ENFILE) { fprintf(stderr, "out of file descriptors\n"); return; } else if (errno != EINTR) { fprintf(stderr, "accept connections error\n"); return; } } } }
void network_t::update() { int num = epoll_wait(epfd, events, max_conn, -1); #pragma omp parallel for for (int i=0; i<num; ++i) { epoll_event* ev = events+i; mydata_t* md = (mydata_t*)ev->data.ptr; if (md->fd == acceptor) { sockaddr_in client_addr; socklen_t sinsize = sizeof(client_addr); int newfd = accept(acceptor, (sockaddr*)&client_addr, &sinsize); while (newfd >= 0) { set_nonblock(newfd); set_linger(newfd, 0); set_nodelay(newfd); auto md = deal_event(epfd, EPOLL_CTL_ADD, newfd, EPOLLIN|EPOLLET, new mydata_t); logon(md); newfd = accept(acceptor, (sockaddr*)&client_addr, &sinsize); } if (errno != EWOULDBLOCK && errno != EAGAIN) { perror("accept newfd"); continue; } } else { if (ev->events & (EPOLLERR | EPOLLHUP)) { md->close(); } else { if (ev->events & EPOLLIN) { md->deal_read(); } if (ev->events & EPOLLOUT) { md->deal_write(); } } if (md->closed.load()) { logoff(md); shutdown(md->fd, SHUT_RDWR); close(md->fd); delete md; } } } }
void vote_destroy(Conn *conn) { VoteConn *vconn = (VoteConn *)conn; if (conn->rbuf) zz_free(conn->rbuf); event_del(&conn->evt); set_linger(conn->sock); close(conn->sock); if (vconn->vote_status == VOTE_TIMEOUT) { DERROR("*** VOTE TIMEOUT, TRY AGAIN\n"); vconn->vote_status = VOTE_CONTINUE; } else if (vconn->vote_status == VOTE_REQUEST || vconn->vote_status == VOTE_WAITING) { /* if (g_cf->role == ROLE_NONE) { DERROR("*** VOTE REQUEST TRY AGAIN\n"); vconn->status = VOTE_CONTINUE; } else { */ DERROR("*** VOTE ABNORMAL ERROR/HOST INVALID\n"); vconn->vote_status = VOTE_CONTINUE; /* g_cf->role = ROLE_NONE; g_runtime->voteid = 0; zz_free(vconn); return; } */ } else if (vconn->vote_status == VOTE_ERR_PARAM) { DERROR("*** VOTE PARAM ERROR\n"); g_cf->role = ROLE_NONE; g_runtime->voteid = 0; zz_free(vconn); return; } if (vconn->vote_status == VOTE_CONTINUE) { DINFO("*** VOTE CONTINUE\n"); request_vote(vconn->id, vconn->idflag, vconn->voteid, vconn->wport); zz_free(vconn); return; } DINFO("*** VOTE OK\n"); zz_free(vconn); }
int read_cmd_response(int fd, char *buf) { int count = client_readn(fd, buf, sizeof(int), iotimeout); if (count == 0) return 0; if (count != sizeof(int)) { DERROR("readn data invalid\n"); set_linger(fd); close(fd); return -1; } memcpy(&count, buf, sizeof(int)); DINFO("count: %d\n", count); int ret = client_readn(fd, buf, count, iotimeout); if (ret != count) { DERROR("readn data invalid\n"); set_linger(fd); close(fd); return -1; } return count; }
int connect_send(int* socket,const int ip,const unsigned short port,const char* buff,const size_t bufflen){ *socket = create_tcpsocket(); set_linger(*socket); connect_port_ip(*socket,ip,port); size_t postsend=0,tmpsend; while(postsend != bufflen){ tmpsend = write(*socket,&buff[postsend],bufflen); if(tmpsend>0){ postsend+=tmpsend; }else{ return 0; } } return postsend; }
int connect_send_close(const int ip,const unsigned short port,const char* buff,const size_t bufflen){ // return how many bytes sent int socket = create_tcpsocket(); set_linger(socket); int success = connect_port_ip(socket,ip,port); if(success) { perror("connect"); fprintf(stderr,"target:%s\n",my_ntoa(ip)); exit(1); return 1; } size_t postsend=0,tmpsend; while(postsend != bufflen){ tmpsend = write(socket,buff,bufflen); if(tmpsend>0){ postsend+=tmpsend; }else{ return postsend; } } close(socket); return postsend; }
int service_vsap(Connection *Conn) { CStr(request,1024); CStr(reqver,128); const char *req; int svsock,shared,clsock,rcode; CStr(myport,256); CStr(sockname,MaxHostNameLen); CStr(peername,MaxHostNameLen); int wcc,rcc; CStr(com,1024); CStr(arg,1024); const char *argp; CStr(opt,32); const char *op; int timeout; int AuthOk; FILE *authout; minit_vsapsv(); if( ToS <= 0 || FromS <= 0 ){ /* If the DST_HOST is not local connect to the master and simple_relay... */ } if( !isMYSELF(DFLT_HOST) ){ daemonlog("E","VSAP relaying to %s:%d\n",DFLT_HOST,DFLT_PORT); if( ToS < 0 ) connect_to_serv(Conn,FromC,ToC,0); relay_svcl(Conn,FromC,ToC,FromS,ToS); close(ToS); return 0; } /* timeout = 300; */ timeout = IO_TIMEOUT; shared = 0; myport[0] = 0; SvSockN = 0; ClSockN = 0; clsock = -1; svsock = -1; reqver[0] = 0; authout = TMPFILE("VSAP-AUTH"); if( doAUTH(Conn,NULL,authout,"vsap","-",0,CVStr("user-xxxx:pass-xxxx"),CVStr("host-xxxx"),NULL,NULL) == EOF ){ AuthOk = 0; }else AuthOk = -1; if( ImMaster ){ sprintf(myport,"%s:%d",DST_HOST,DST_PORT); }else for(;;){ if( DDI_fgetsFromCbuf(Conn,AVStr(request),sizeof(request),NULL) == 0 ) { int closed = 0; for(;;){ if( PollIn(FromC,1*1000) != 0 ) break; closed |= checkCloseOnTimeout(1); if( 0 <= clsock && !IsAlive(clsock) ){ daemonlog("E","## disconnected by peer\n"); SockPrintf(ToC,"%s %d %s.\r\n",VER,NO_GENERIC_BYE,"disconnected by peer"); close(clsock);del_clsock(clsock); goto EXIT; } } if( (rcc = RecvLine(FromC,request,sizeof(request))) <= 0 ) break; } daemonlog("D","CLIENT-SAYS: %s",request); daemonlog("E","CLIENT-SAYS: %s",request); req = request; if( strncmp(req,"VSAP/",5) == 0 ) req = wordScan(req,reqver); argp = wordScan(req,com); arg[0] = 0; lineScan(argp,arg); if( strcasecmp(com,"AUTH") == 0 ){ CStr(ahost,MaxHostNameLen); ahost[0] = 0; if( doAUTH(Conn,NULL,authout,"vsap","-",0,AVStr(arg),AVStr(ahost),NULL,NULL) == EOF ){ }else{ AuthOk = 1; SockPrintf(ToC,"%s %d OK\r\n",VER,OK_GENERIC); continue; } } if( AuthOk == 0 ){ SockPrintf(ToC,"%s %d forbidden\r\n",VER,NO_PERMISSION); sv1log("WITH AUTHORIZER, but NO AUTH from client\n"); break; } if( strcasecmp(com,"ECHO") == 0 ){ CStr(stime,64); StrftimeLocal(AVStr(stime),sizeof(stime),TIMEFORM_HTTPD,time(0),0); SockPrintf(ToC,"%s %d [%s] %s\r\n",VER,OK_GENERIC, stime,arg); }else if( strcasecmp(com,"CONNECT") == 0 ){ strcpy(myport,arg); if( !vsap_permit(Conn,myport) ) break; clsock = do_connect(svsock,myport,ToC); if( clsock < 0 ) break; }else if( strcasecmp(com,"BIND") == 0 ){ CStr(opts,1024); opts[0] = 0; Xsscanf(arg,"%s %[^\r\n]",AVStr(myport),AVStr(opts)); if( !vsap_permit(Conn,myport) ) break; svsock = do_bind(-1,AVStr(myport),opts,&shared,AVStr(sockname),ToC); if( svsock < 0 ) break; }else if( strcasecmp(com,"LISTEN") == 0 ){ int nlisten = atoi(arg); Socket1("VSAP",svsock,NULL,NULL,NULL,VStrANYPORT,ANYPORT,nlisten,NULL,0); SockPrintf(ToC,"%s %d listen ok.\r\n",VER,OK_LISTEN); }else if( strcasecmp(com,"ACCEPT") == 0 ){ int priority; if( Conn->cl_count <= 1 ) priority = 0; else priority = 1; clsock = do_accept(myport,arg,shared,priority,FromC,ToC); if( !shared ) svsock = -1; if( clsock < 0 ){ wcc = SockPrintf(ToC,"%s %d accept fail\r\n", VER,NO_ACCEPT); break; } add_clsock(clsock); if( myport[0] == '/' ){ strcpy(sockname,myport); strcpy(peername,myport); }else getpairName(clsock,AVStr(sockname),AVStr(peername)); wcc = SockPrintf(ToC,"%s %d %d %s %s accepted.\r\n", VER,OK_ACCEPT,ClSockN,sockname,peername); }else if( strcasecmp(com,"QUIT") == 0 ){ SockPrintf(ToC,"%s %d bye.\r\n",VER,OK_BYE); break; }else if( strcasecmp(com,"FORWARD") == 0 ){ do_forward(Conn,myport,arg,shared,svsock,0,FromC,ToC); }else if( strcasecmp(com,"RELAY") == 0 ){ /* -t timeout */ for( op = arg; *op == '-'; ){ if( strneq(op,"-t=",3) ){ int to; op = numscanX(op+3,AVStr(opt),sizeof(opt)); to = atoi(opt); if( to < timeout ) timeout = to; }else{ break; } } tcp_relay2(timeout*1000,FromC,clsock,clsock,ToC); /* set_linger(clsock,10); */ set_linger(clsock,LIN_TIMEOUT); close(clsock);del_clsock(clsock); break; }else if( strcasecmp(com,"PROXY") == 0 ){ ToS = FromS = ToC; ToC = FromC = clsock; daemonlog("E","##### VSAP switch protocol to '%s'\n",arg); if( strcmp(arg,"http")==0 ) service_http(Conn); else if( strcmp(arg,"ftp")==0 ) service_ftp(Conn); set_linger(clsock,10); close(clsock);del_clsock(clsock); break; }else { /* wcc = write(clsock,req,rcc); tcp_relay2(timeout*1000,FromC,clsock,clsock,ToC); */ SockPrintf(ToC,"%s %d %s",VER,NO_GENERIC,request); } } EXIT: fclose(authout); return 0; }
int main(int argc, char **argv) { if (argc < 6) { DERROR("Usage: %s <id> <idflag> <vote_id> <port> <I/O timeout>\n", argv[0]); exit(-1); } set_signal(); id = atoi(argv[1]); idflag = atoi(argv[2]); vote_id = atoi(argv[3]); port = atoi(argv[4]); iotimeout = atoi(argv[5]); //DINFO("id: %llu, idflag: %d\nvote_id: %llu\nport: %d\ntimeout: %d\n", id, idflag, vote_id, port, iotimeout); listenfd = socket(AF_INET, SOCK_STREAM, 0); if (listenfd == -1) { DERROR("socket: %s\n", strerror(errno)); MEMLINK_EXIT; } int flag = 1; setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag)); setsockopt(listenfd, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof(flag)); struct sockaddr_in s; bzero(&s, sizeof(s)); s.sin_family = AF_INET; s.sin_addr.s_addr = htonl(INADDR_ANY); s.sin_port = htons(port); int ret; ret = bind(listenfd, (struct sockaddr *)&s, sizeof(s)); if (ret == -1) { DERROR("bind: %s\n", strerror(errno)); MEMLINK_EXIT; } if (listen(listenfd, 128) == -1) { DERROR("listen: %s\n", strerror(errno)); MEMLINK_EXIT; } int clientfd = socket(AF_INET, SOCK_STREAM, 0); if (clientfd == -1) { DERROR("socket: %s\n", strerror(errno)); MEMLINK_EXIT; } setsockopt(clientfd, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof(flag)); s.sin_family = AF_INET; s.sin_port = htons(11010); inet_pton(AF_INET, VOTE_HOST, &s.sin_addr); ret = connect(clientfd, (struct sockaddr *)&s, sizeof(s)); if (ret == -1) { DERROR("connect: %s\n", strerror(errno)); MEMLINK_EXIT; } char buf[1024]; int count = pack_vote(buf, id, idflag, vote_id, port); cmd_vote_unpack(buf+CMD_REQ_HEAD_LEN); if (client_writen(clientfd, buf, count, iotimeout) != count) { DERROR("write count should be %d\n", count); set_linger(clientfd); close(clientfd); return -1; } fd_set rset; FD_ZERO(&rset); int closed = 0; while (1) { if (closed == 0) FD_SET(clientfd, &rset); FD_SET(listenfd, &rset); int maxfd = clientfd > listenfd ? clientfd : listenfd; ret = select(maxfd+1, &rset, NULL, NULL, NULL); if (ret < 0) { if (errno == EINTR) { continue; } else { DERROR("*** select error: %s\n", strerror(errno)); exit(-1); } } if (FD_ISSET(listenfd, &rset)) { clientfd = accept(listenfd, NULL, 0); closed = 0; } if (FD_ISSET(clientfd, &rset)) { count = read_cmd_response(clientfd, buf); if (count < 0) { DERROR("response error\n"); return -1; } else if (count == 0) { DINFO("*** voter closed\n"); close(clientfd); closed = 1; FD_CLR(clientfd, &rset); continue; } char *ptr = buf; char ip[INET_ADDRSTRLEN]; uint16_t pt; uint64_t v_id; uint8_t cmd; short rcode; memcpy(&cmd, ptr, sizeof(cmd)); ptr += sizeof(cmd); count -= sizeof(cmd); DINFO("cmd: %u\n", cmd); switch (cmd) { case CMD_VOTE_DETECT: reply_pack(clientfd); break; case CMD_VOTE_UPDATE: DINFO("*** UPDATE\n"); ret = unpack_voteid(ptr, &v_id); DINFO("voteid: %llu\n", (unsigned long long)v_id); ptr += ret; count -= ret; if (master == 1) { DINFO("I'm master\n"); } else { DINFO("I'm backup\n"); } while (count > 0) { ret = unpack_votehost(ptr, ip, &pt); DINFO("HOST: %s(%d)\n", ip, pt); ptr += ret; count -= ret; } if (master == 1) { replyok(clientfd); } else { replyerr(clientfd); } break; case CMD_VOTE: memcpy(&rcode, ptr, sizeof(rcode)); ptr += sizeof(rcode); count -= sizeof(rcode); if (rcode == CMD_VOTE_BACKUP) master = 0; switch (rcode) { case CMD_VOTE_WAIT: DINFO("I should wait vote finished\n"); break; case CMD_VOTE_MASTER: master = 1; case CMD_VOTE_BACKUP: DINFO("VOTE SUCCESS\n"); ret = unpack_voteid(ptr, &v_id); DINFO("voteid: %llu\n", (unsigned long long)v_id); vote_id = v_id; ptr += ret; count -= ret; if (master == 1) { DINFO("I'm master\n"); } else { DINFO("I'm backup\n"); } while (count > 0) { ret = unpack_votehost(ptr, ip, &pt); DINFO("HOST: %s(%d)\n", ip, pt); ptr += ret; count -= ret; } replyok(clientfd); break; case CMD_VOTE_NONEED: DINFO("*** no need vote\n"); break; case MEMLINK_ERR_VOTE_PARAM: DERROR("id flag error: %d\n", idflag); break; default: break; } break; default: break; } } } return 0; }
int send_lpr(DGC*Conn,PCStr(lphost),int lpport,PCStr(queue),FILE *dfp,int dlen,PCStr(user),PCStr(fname),PVStr(stat)) { FILE *ts,*fs; CStr(job,64); CStr(resp,1024); int rcc; int jnum; CStr(src_files,64); int data_size,ctrl_size; CStr(data_name,64); CStr(ctrl_name,64); CStr(orig_host,64); CStr(orig_user,64); const char *pdata; CStr(ctrl_data,1024); refQStr(cfp,ctrl_data); /**/ const char *fmt; if( queue == NULL || *queue == 0 ) queue = DEFAULT_QUEUE; jnum = time(0) % 1000; data_size = dlen; pdata = freadfile(dfp,&data_size); if( fname ) strcpy(src_files,fname); else strcpy(src_files,"standard input"); syslog_ERROR("Data Size: %d\n",data_size); fmt = "f"; getAgentInfo(Conn,user,AVStr(orig_host),AVStr(orig_user)); sprintf(data_name,"dfA%03d%s",jnum,orig_host); sprintf(ctrl_name,"cfA%03d%s",jnum,orig_host); sprintf(cfp,"%c%s\n",CF_HOSTNAME,orig_host); cfp += strlen(cfp); sprintf(cfp,"%c%s\n",CF_USERID, orig_user); cfp += strlen(cfp); sprintf(cfp,"%c%s\n",CF_JOBNAME, src_files); cfp += strlen(cfp); sprintf(cfp,"%c%s\n",CF_CLASS, orig_host); cfp += strlen(cfp); sprintf(cfp,"%c%s\n",CF_BANNER, orig_user); cfp += strlen(cfp); sprintf(cfp,"%s%s\n",fmt, data_name); cfp += strlen(cfp); sprintf(cfp,"%c%s\n",CF_UNLINK, data_name); cfp += strlen(cfp); sprintf(cfp,"%c%s\n",CF_FILENAME,src_files); cfp += strlen(cfp); ctrl_size = strlen(ctrl_data); syslog_DEBUG("Control File:\n%s",ctrl_data); if( open_lpr(lphost,lpport,&ts,&fs) != 0 ){ if( stat ) sprintf(stat,"can't connect to the LPR server\n"); return -1; } fprintf(ts,"%c%s\n",JC_RECEIVE,queue); fflush(ts); rcc = fread(resp,1,1,fs); syslog_DEBUG("> %-10s %d code=%d\n","RECEIVE",rcc,resp[0]); fprintf(ts,"%c%d %s\n",RJ_DATA,data_size,data_name); fflush(ts); syslog_DEBUG("> %-10s %d %s\n","RJ_DATA",data_size,data_name); rcc = fread(resp,1,1,fs); syslog_DEBUG("< %-10s %d code=%d\n","RJ_DATA",rcc,resp[0]); fwrite(pdata,1,data_size,ts); free((char*)pdata); fflush(ts); fputc(0,ts); fflush(ts); rcc = fread(resp,1,1,fs); syslog_DEBUG("> %-10s %d code=%d\n","RJ_DATA",rcc,resp[0]); fprintf(ts,"%c%d %s\n",RJ_CONTROL,ctrl_size,ctrl_name); fflush(ts); syslog_DEBUG("< %-10s %d %s\n","RJ_CONTROL",ctrl_size,ctrl_name); rcc = fread(resp,1,1,fs); syslog_DEBUG("> %-10s %d code=%d\n","RJ_CONTROL",rcc,resp[0]); fputs(ctrl_data,ts); fflush(ts); fputc(0,ts); fflush(ts); rcc = fread(resp,1,1,fs); syslog_DEBUG("< %-10s %d code=%d\n","RJ_CONTROL",rcc,resp[0]); set_linger(fileno(ts),30); fclose(ts); fclose(fs); stat_lpr(lphost,lpport,queue,"","",AVStr(stat)); return data_size; }
int service_lpr(DGC*Conn,int _1,int _2,int fromC,int toC,PCStr(svproto),PCStr(svhost),int svport,PCStr(svpath)) { FILE *ts,*fs,*fc,*tc; CStr(req,1024); CStr(resp,0x8000); char op; int nowait; FILE *tmp; const char *host = svhost; int port = svport; LprJob lpj_buf, *lpj = &lpj_buf; nowait = getenv("LPR_NOWAIT") != NULL; /* if( withMount || filter_withCFI(Conn,X_FTOSV) ) nowait = 1; */ if( nowait ) fc = fdopen(dup(fromC),"r"); else fc = fdopen(fromC,"r"); tc = fdopen(toC,"w"); bzero(lpj,sizeof(LprJob)); op = 0; if( nowait ){ tmp = TMPFILE("LPR"); op = relay_commands(lpj,tmp,NULL,tc,fc); fclose(fc); fc = tmp; fflush(tmp); fseek(tmp,0,0); if( op == 0 ){ syslog_ERROR("disconnect with the client.\n"); fclose(tc); tc = NULL; closedups(0); /* maybe necessary for Win32 ? */ } /* MOUNT host,port using CONTROL DATA */ /* conver the data */ /* { int off,siz,rcc; const char *buff; sv1log("#### DATA:%d+%d CTRL:%d+%d SIZE=%d\n", lpj->l_data_off, lpj->l_data_siz, lpj->l_ctrl_off, lpj->l_ctrl_siz, lpj->l_off); if( siz = lpj->l_data_siz ){ fseek(tmp,lpj->l_data_off,0); buff = (char*)malloc(lpj->l_data_siz+1); rcc = fread (buff,1,lpj->l_data_siz,tmp); buff[rcc] = 0; fprintf(stderr,"---\n%s---\n",buff); free(buff); fseek(tmp,0,0); } } */ } if( open_lpr(host,port,&ts,&fs) != 0 ){ syslog_ERROR("cannot connect to LPR %s:%d\n",host,port); resp[0] = (char)-1; IGNRETP write(toC,resp,1); return -1; } relay_commands(lpj,ts,fs,tc,fc); if( tc != NULL ){ switch( op ){ case JC_SENDQSTATS: case JC_SENDQSTATL: fprintf(tc,"#### NOWAIT MODE LPR-DeleGate/%s ####\r\n", DELEGATE_ver()); } fclose(tc); } fclose(fc); set_linger(fileno(ts),30); fclose(ts); fclose(fs); return 0; }