Ejemplo n.º 1
0
static void* masterproxy_acceptor(void *args) {
	pthread_t clientthread;
	pthread_attr_t thattr;
	int sock;
	(void)args;

	pthread_attr_init(&thattr);
	pthread_attr_setstacksize(&thattr,0x100000);
	pthread_attr_setdetachstate(&thattr,PTHREAD_CREATE_DETACHED);

	while (terminate==0) {
		sock = tcptoaccept(lsock,1000);
		if (sock>=0) {
			int *s = malloc(sizeof(int));
			// memory is freed inside pthread routine !!!
			*s = sock;
			tcpnodelay(sock);
			if (pthread_create(&clientthread,&thattr,masterproxy_server,s)<0) {
				free(s);
				tcpclose(sock);
			}
		}
	}

	pthread_attr_destroy(&thattr);
	return NULL;
}
Ejemplo n.º 2
0
Archivo: client.c Proyecto: twonly/mis
void* ppfs_fsinit( struct fuse_conn_info* conn ) { //connect to MDS
  fprintf(stderr, "ppfs_fsinit\n");
  if((fd = tcpsocket())<0) {
    fprintf(stderr, "can't create socket\n");
    exit(1);
  } else {
    fprintf(stderr, "fd:%d\n", fd);
  }

  tcpnodelay(fd);
  if(tcpstrconnect(fd, ip, MDS_PORT_STR)<0) {
    fprintf(stderr, "can't connect to MDS (%s:%s)\n", ip, port);
    fd = -1;

    exit(1);
  }

  fprintf(stderr, "ppfs_init create socket: %u\n", fd);

  local_mds.sockfd = fd;
	tcpgetpeer(fd,&(local_mds.peerip),NULL);

  remote_mds.sockfd = -1;
  remote_mds.peerip = -1;
}
Ejemplo n.º 3
0
int masterproxy_init(void) {
	pthread_attr_t thattr;

	lsock = tcpsocket();
	if (lsock<0) {
		//mfs_errlog(LOG_ERR,"main master server module: can't create socket");
		return -1;
	}
	tcpnonblock(lsock);
	tcpnodelay(lsock);
	// tcpreuseaddr(lsock);
	if (tcpsetacceptfilter(lsock)<0 && errno!=ENOTSUP) {
		// mfs_errlog_silent(LOG_NOTICE,"master proxy: can't set accept filter");
	}
	if (tcpstrlisten(lsock,"127.0.0.1",0,100)<0) {
		// mfs_errlog(LOG_ERR,"main master server module: can't listen on socket");
		tcpclose(lsock);
		lsock = -1;
		return -1;
	}
	if (tcpgetmyaddr(lsock,&proxyhost,&proxyport)<0) {
		tcpclose(lsock);
		lsock = -1;
		return -1;
	}

	terminate = 0;
	pthread_attr_init(&thattr);
	pthread_attr_setstacksize(&thattr,0x100000);
	//pthread_create(&proxythread,&thattr,masterproxy_loop,NULL);
	pthread_create(&proxythread,&thattr,masterproxy_acceptor,NULL);
	pthread_attr_destroy(&thattr);

	return 1;
}
Ejemplo n.º 4
0
int matomlserv_init(void) {
	ListenHost = cfg_getstr("MATOML_LISTEN_HOST","*");
	ListenPort = cfg_getstr("MATOML_LISTEN_PORT","9419");

	lsock = tcpsocket();
	if (lsock<0) {
		mfs_errlog(LOG_ERR,"master <-> metaloggers module: can't create socket");
		return -1;
	}
	tcpnonblock(lsock);
	tcpnodelay(lsock);
	tcpreuseaddr(lsock);
	if (tcpsetacceptfilter(lsock)<0 && errno!=ENOTSUP) {
		mfs_errlog_silent(LOG_NOTICE,"master <-> metaloggers module: can't set accept filter");
	}
	if (tcpstrlisten(lsock,ListenHost,ListenPort,100)<0) {
		mfs_arg_errlog(LOG_ERR,"master <-> metaloggers module: can't listen on %s:%s",ListenHost,ListenPort);
		return -1;
	}
	mfs_arg_syslog(LOG_NOTICE,"master <-> metaloggers module: listen on %s:%s",ListenHost,ListenPort);

	matomlservhead = NULL;
	ChangelogSecondsToRemember = cfg_getuint16("MATOML_LOG_PRESERVE_SECONDS",600);
	if (ChangelogSecondsToRemember>3600) {
		syslog(LOG_WARNING,"Number of seconds of change logs to be preserved in master is too big (%"PRIu16") - decreasing to 3600 seconds",ChangelogSecondsToRemember);
		ChangelogSecondsToRemember=3600;
	}
	main_reloadregister(matomlserv_reload);
	main_destructregister(matomlserv_term);
    main_canexitregister(matomlserv_canexit);
	main_pollregister(matomlserv_desc,matomlserv_serve);
	main_timeregister(TIMEMODE_SKIP_LATE,3600,0,matomlserv_status);
	return 0;
}
Ejemplo n.º 5
0
int matomlserv_init(void) {
	ListenHost = cfg_getstr("MATOML_LISTEN_HOST","*");
	ListenPort = cfg_getstr("MATOML_LISTEN_PORT","9419");

	lsock = tcpsocket();
	if (lsock<0) {
		mfs_errlog(LOG_ERR,"master <-> metaloggers module: can't create socket");
		return -1;
	}
	tcpnonblock(lsock);
	tcpnodelay(lsock);
	tcpreuseaddr(lsock);
	if (tcpsetacceptfilter(lsock)<0 && errno!=ENOTSUP) {
		mfs_errlog_silent(LOG_NOTICE,"master <-> metaloggers module: can't set accept filter");
	}
	if (tcpstrlisten(lsock,ListenHost,ListenPort,100)<0) {
		mfs_errlog(LOG_ERR,"master <-> metaloggers module: can't listen on socket");
		return -1;
	}
	mfs_arg_syslog(LOG_NOTICE,"master <-> metaloggers module: listen on %s:%s",ListenHost,ListenPort);

	matomlservhead = NULL;
	main_reloadregister(matomlserv_reload);
	main_destructregister(matomlserv_term);
	main_pollregister(matomlserv_desc,matomlserv_serve);
	main_timeregister(TIMEMODE_SKIP_LATE,3600,0,matomlserv_status);
	return 0;
}
Ejemplo n.º 6
0
void masterconn_connected(masterconn *eptr) {
	double now;

	now = monotonic_seconds();

	tcpnodelay(eptr->sock);
	eptr->mode = DATA;
	eptr->lastread = now;
	eptr->lastwrite = now;
	eptr->input_bytesleft = 8;
	eptr->input_startptr = eptr->input_hdr;
	eptr->input_end = 0;
	eptr->input_packet = NULL;
	eptr->inputhead = NULL;
	eptr->inputtail = &(eptr->inputhead);
	eptr->outputhead = NULL;
	eptr->outputtail = &(eptr->outputhead);
	eptr->conncnt++;
	eptr->masterversion = 0;
	eptr->hlstatus = 0;
	eptr->gotrndblob = 0;
	memset(eptr->rndblob,0,32);
	eptr->registerstate = UNREGISTERED;

	masterconn_sendregister(eptr);
}
Ejemplo n.º 7
0
int csserv_init(void) {
	ListenHost = cfg_getstr("CSSERV_LISTEN_HOST","*");
	ListenPort = cfg_getstr("CSSERV_LISTEN_PORT",DEFAULT_CS_DATA_PORT);

	lsock = tcpsocket();
	if (lsock<0) {
		mfs_errlog(LOG_ERR,"main server module: can't create socket");
		return -1;
	}
	tcpnonblock(lsock);
	tcpnodelay(lsock);
	tcpreuseaddr(lsock);
	tcpresolve(ListenHost,ListenPort,&mylistenip,&mylistenport,1);
	if (tcpnumlisten(lsock,mylistenip,mylistenport,100)<0) {
		mfs_errlog(LOG_ERR,"main server module: can't listen on socket");
		return -1;
	}
	if (tcpsetacceptfilter(lsock)<0 && errno!=ENOTSUP) {
		mfs_errlog_silent(LOG_NOTICE,"main server module: can't set accept filter");
	}
	mfs_arg_syslog(LOG_NOTICE,"main server module: listen on %s:%s",ListenHost,ListenPort);

	csservhead = NULL;
	main_reload_register(csserv_reload);
	main_destruct_register(csserv_term);
	main_poll_register(csserv_desc,csserv_serve);

	return 0;
}
Ejemplo n.º 8
0
int client_socket (char * host, char * port) {
    int status;
    int lsock = tcpsocket();
    if (lsock<0) {
        logging(LOG_ERROR, "can't create socket !!!");
        return -1;
    }
    if (tcpnonblock(lsock)<0) {
        logging(LOG_ERROR, "set nonblock, error: %m");
        tcpclose(lsock);
        return -1;
    }
    status = tcpstrconnect(lsock, host, port);
    if (status<0) {
        logging(LOG_WARN, "connect failed, error: %m");
        tcpclose(lsock);
        return -1;
    }
    if (status==0) { // connected immediately
        logging(LOG_INFO,"connected immediately");
        tcpnodelay(lsock);
    } else {
        logging(LOG_INFO,"connecting to %s:%s...", host, port);
    }
    return lsock;
}
Ejemplo n.º 9
0
static int write_data_refresh_connection(uint32_t inode, uint32_t indx, uint64_t *chunkid)
{
	uint32_t ip;
	uint16_t port;
	uint8_t status;

	if (rw_sock >= 0) {
		tcpclose(rw_sock);
		rw_sock = -1;
	}

	status = fs_writechunk(&ip,&port, chunkid, inode, indx);
	if (status != 0) {
		fprintf(stderr, "status error\n");
		return -2;
	}

	rw_sock = tcpsocket();
	if (rw_sock < 0) {
		fprintf(stderr,"can't create tcp socket\n");
		return -1;
	}
	if (tcpnodelay(rw_sock)<0) {
		fprintf(stderr,"can't set TCP_NODELAY\n");
	}
	if (tcpnumconnect(rw_sock, ip, port)<0) {
		fprintf(stderr,"can't connect to (%d.%d.%d.%d:%u)\n",
		ip/(256*256*256)%256, ip/(256*256)%256, ip/256%256, ip%256, port);
		tcpclose(rw_sock);
		rw_sock = -1;
		return -1;
	}
	return 0;
}
Ejemplo n.º 10
0
void matoslaserv_serve(int epoll_fd,int count,struct epoll_event *pdesc) {
	//uint32_t now=main_time();
	serventry *eptr,*weptr;
	int ns;
	
	weptr = (serventry *)pdesc[count].data.ptr;
	if ((weptr->listen_sock == 1) && (pdesc[count].events & EPOLLIN)) {
		ns=tcpaccept(lsock);
		if (ns<0) {
			MFSLOG(LOG_INFO,"Master<->sla socket: accept error: %m");
		} else {
			struct epoll_event ev;
			tcpnonblock(ns);
			tcpnodelay(ns);
			eptr = (serventry *)malloc(sizeof(serventry));
			eptr->next = matoslaservhead;
			matoslaservhead = eptr;
			eptr->sock = ns;
			eptr->mode = HEADER;
			eptr->lastread = eptr->lastwrite = get_current_time();
			eptr->inputpacket.next = NULL;
			eptr->inputpacket.bytesleft = 8;
			eptr->inputpacket.startptr = eptr->hdrbuff;
			eptr->inputpacket.packet = NULL;
			eptr->outputhead = NULL;
			eptr->outputtail = &(eptr->outputhead);
			eptr->timeout = 120;
			
			tcpgetpeer(eptr->sock,&(eptr->servip),NULL);
			eptr->servstrip = matoslaserv_makestrip(eptr->servip);
			eptr->version=0;
			eptr->metafd=-1;

			eptr->listen_sock = 0;
                    eptr->connection = 4;

			ev.data.ptr = eptr;
                        ev.events = EPOLLIN | EPOLLOUT;
                        epoll_ctl(epoll_fd,EPOLL_CTL_ADD,ns,&ev);
		}
	}
	if(weptr->listen_sock == 0) {
		if (pdesc[count].events & (EPOLLERR|EPOLLHUP)) {
			weptr->mode = KILL;
		}
		if ((pdesc[count].events & EPOLLIN) && weptr->mode!=KILL) {
			matoslaserv_read(weptr);
			weptr->lastread = get_current_time();			
		}
		if ((pdesc[count].events & EPOLLOUT) && weptr->mode!=KILL && weptr->outputhead!=NULL) {
			matoslaserv_write(weptr);
			weptr->lastwrite = get_current_time();			
		}
	}
}
Ejemplo n.º 11
0
void masterconn_connected(serventry *eptr) {
	tcpnodelay(eptr->sock);
	eptr->mode=HEADER;
	eptr->inputpacket.next = NULL;
	eptr->inputpacket.bytesleft = 8;
	eptr->inputpacket.startptr = eptr->hdrbuff;
	eptr->inputpacket.packet = NULL;
	eptr->outputtail = &(eptr->outputhead);

	masterconn_sendregister(eptr);
	eptr->lastread = eptr->lastwrite = get_current_time();
}
Ejemplo n.º 12
0
void matomlserv_reload(void) {
	char *oldListenHost,*oldListenPort;
	int newlsock;

	oldListenHost = ListenHost;
	oldListenPort = ListenPort;
	ListenHost = cfg_getstr("MATOML_LISTEN_HOST","*");
	ListenPort = cfg_getstr("MATOML_LISTEN_PORT","9419");
	if (strcmp(oldListenHost,ListenHost)==0 && strcmp(oldListenPort,ListenPort)==0) {
		free(oldListenHost);
		free(oldListenPort);
		mfs_arg_syslog(LOG_NOTICE,"master <-> metaloggers module: socket address hasn't changed (%s:%s)",ListenHost,ListenPort);
		return;
	}

	newlsock = tcpsocket();
	if (newlsock<0) {
		mfs_errlog(LOG_WARNING,"master <-> metaloggers module: socket address has changed, but can't create new socket");
		free(ListenHost);
		free(ListenPort);
		ListenHost = oldListenHost;
		ListenPort = oldListenPort;
		return;
	}
	tcpnonblock(newlsock);
	tcpnodelay(newlsock);
	tcpreuseaddr(newlsock);
	if (tcpsetacceptfilter(newlsock)<0 && errno!=ENOTSUP) {
		mfs_errlog_silent(LOG_NOTICE,"master <-> metaloggers module: can't set accept filter");
	}
	if (tcpstrlisten(newlsock,ListenHost,ListenPort,100)<0) {
		mfs_arg_errlog(LOG_ERR,"master <-> metaloggers module: socket address has changed, but can't listen on socket (%s:%s)",ListenHost,ListenPort);
		free(ListenHost);
		free(ListenPort);
		ListenHost = oldListenHost;
		ListenPort = oldListenPort;
		tcpclose(newlsock);
		return;
	}
	mfs_arg_syslog(LOG_NOTICE,"master <-> metaloggers module: socket address has changed, now listen on %s:%s",ListenHost,ListenPort);
	free(oldListenHost);
	free(oldListenPort);
	tcpclose(lsock);
	lsock = newlsock;

	ChangelogSecondsToRemember = cfg_getuint16("MATOML_LOG_PRESERVE_SECONDS",600);
	if (ChangelogSecondsToRemember>3600) {
		syslog(LOG_WARNING,"Number of seconds of change logs to be preserved in master is too big (%"PRIu16") - decreasing to 3600 seconds",ChangelogSecondsToRemember);
		ChangelogSecondsToRemember=3600;
	}
}
Ejemplo n.º 13
0
void masterconn_connected(masterconn *eptr) {
    tcpnodelay(eptr->sock);
    eptr->mode=HEADER;
    eptr->inputpacket.next = NULL;
    eptr->inputpacket.bytesleft = 8;
    eptr->inputpacket.startptr = eptr->hdrbuff;
    eptr->inputpacket.packet = NULL;
    eptr->outputhead = NULL;
    eptr->outputtail = &(eptr->outputhead);

    masterconn_sendregister(eptr);
    masterconn_metadownloadinit();
    eptr->lastread = eptr->lastwrite = main_time();
}
Ejemplo n.º 14
0
//向Master注册,调用masterconn_sendregister()封装注册packet
//调用:masterconn_initconnect()
void masterconn_connected(masterconn *eptr) {
#ifdef BGJOBS
	eptr->jpool = job_pool_new(10,BGJOBSCNT,&(eptr->jobfd));
#endif
	tcpnodelay(eptr->sock);
	eptr->mode=HEADER;
	eptr->inputpacket.next = NULL;
	eptr->inputpacket.bytesleft = 8;
	eptr->inputpacket.startptr = eptr->hdrbuff;
	eptr->inputpacket.packet = NULL;
	eptr->outputhead = NULL;
	eptr->outputtail = &(eptr->outputhead);

	masterconn_sendregister(eptr);
	eptr->lastread = eptr->lastwrite = main_time();
}
Ejemplo n.º 15
0
void csserv_reload(void) {
	char *oldListenHost,*oldListenPort;
	int newlsock;

//	ThreadedServer = 1-ThreadedServer;

	oldListenHost = ListenHost;
	oldListenPort = ListenPort;
	ListenHost = cfg_getstr("CSSERV_LISTEN_HOST","*");
	ListenPort = cfg_getstr("CSSERV_LISTEN_PORT",DEFAULT_CS_DATA_PORT);
	if (strcmp(oldListenHost,ListenHost)==0 && strcmp(oldListenPort,ListenPort)==0) {
		free(oldListenHost);
		free(oldListenPort);
		mfs_arg_syslog(LOG_NOTICE,"main server module: socket address hasn't changed (%s:%s)",ListenHost,ListenPort);
		return;
	}

	newlsock = tcpsocket();
	if (newlsock<0) {
		mfs_errlog(LOG_WARNING,"main server module: socket address has changed, but can't create new socket");
		free(ListenHost);
		free(ListenPort);
		ListenHost = oldListenHost;
		ListenPort = oldListenPort;
		return;
	}
	tcpnonblock(newlsock);
	tcpnodelay(newlsock);
	tcpreuseaddr(newlsock);
	if (tcpstrlisten(newlsock,ListenHost,ListenPort,100)<0) {
		mfs_arg_errlog(LOG_ERR,"main server module: socket address has changed, but can't listen on socket (%s:%s)",ListenHost,ListenPort);
		free(ListenHost);
		free(ListenPort);
		ListenHost = oldListenHost;
		ListenPort = oldListenPort;
		tcpclose(newlsock);
		return;
	}
	if (tcpsetacceptfilter(newlsock)<0 && errno!=ENOTSUP) {
		mfs_errlog_silent(LOG_NOTICE,"main server module: can't set accept filter");
	}
	mfs_arg_syslog(LOG_NOTICE,"main server module: socket address has changed, now listen on %s:%s",ListenHost,ListenPort);
	free(oldListenHost);
	free(oldListenPort);
	tcpclose(lsock);
	lsock = newlsock;
}
Ejemplo n.º 16
0
int matoslaserv_init() {
	ListenHost = cfg_getstr("MATOSLA_LISTEN_HOST","*");
	ListenPort = cfg_getstr("MATOSLA_LISTEN_PORT","9423");
	BindHost = cfg_getstr("BIND_HOST","*");
	MaxReconnect = cfg_getuint32("MAX_RECONNECT",10);
	sla_worker_addr[0].host = cfg_getstr("SLA_SYNC_WORKER_HOST_1","*");
	sla_worker_addr[0].port = cfg_getstr("SLA_SYNC_WORKER_PORT_1","9422");
        sla_worker_addr[1].host = cfg_getstr("SLA_SYNC_WORKER_HOST_2","*");
        sla_worker_addr[1].port = cfg_getstr("SLA_SSYNC_WORKER_PORT_2","9422");
        sla_worker_addr[2].host = cfg_getstr("SLA_SSYNC_WORKER_HOST_3","*");
        sla_worker_addr[2].port = cfg_getstr("SLA_SSYNC_WORKER_PORT_3","9422");
        sla_worker_addr[3].host = cfg_getstr("SLA_SSYNC_WORKER_HOST_4","*");
        sla_worker_addr[3].port = cfg_getstr("SLA_SSYNC_WORKER_PORT_4","9422");

	first_add_listen_sock = 0;
	lsock = tcpsocket();
	if (lsock<0) {
		MFSLOG(LOG_ERR,"matosla: socket error: %m");
		fprintf(msgfd,"master <-> metaloggers module: can't create socket\n");
		return -1;
	}
	tcpnonblock(lsock);
	tcpnodelay(lsock);
	tcpreuseaddr(lsock);
	if (sla_worker_addr_resolve()<0) {
		MFSLOG(LOG_NOTICE,"sla_worker_addr_resolve failed");
	}
	if (tcpsetacceptfilter(lsock)<0) {
		MFSLOG(LOG_NOTICE,"matosla: can't set accept filter: %m");
	}
	if (tcpstrlisten(lsock,ListenHost,ListenPort,1024)<0) {
		MFSLOG(LOG_ERR,"matosla: listen error: %m");
		fprintf(msgfd,"master <-> metaloggers module: can't listen on socket\n");
		return -1;
	}
	MFSLOG(LOG_NOTICE,"matosla: listen on %s:%s",ListenHost,ListenPort);
	fprintf(msgfd,"master <-> metaloggers module: listen on %s:%s\n",ListenHost,ListenPort);

	matoslaservhead = NULL;
	main_destructregister(matoslaserv_term);
	main_epollregister(matoslaserv_desc,matoslaserv_serve);
	return 0;
}
Ejemplo n.º 17
0
/* ning:
 * 这是从 mfs matomlserv.c, matocsserv.c, matocuserv.c 三个代码里面提出来的公用代码
*/
int server_socket(char * host, char * port){
    int lsock = tcpsocket();
    if (lsock<0) {
        logging(LOG_ERROR, "can't create socket !!!");
        return -1;
    }
    tcpnonblock(lsock);
    tcpnodelay(lsock);
    tcpreuseaddr(lsock);
    if (tcpsetacceptfilter(lsock)<0) {
        logging(LOG_INFO,"can't set accept filter: %m"); //TODO: I do not know what this for
    }
    if (tcpstrlisten(lsock, host ,port,100)<0) {
        logging(LOG_ERROR,"can't Listen on socket : %m");
        return -1;
    }
    logging(LOG_INFO,"listen on %s:%s", host, port);
    return lsock;
}
Ejemplo n.º 18
0
Archivo: client.c Proyecto: twonly/mis
int serv_connect(ppfs_conn_entry* e,int ip,int port){
  int fd = tcpsocket();
  if(fd < 0){
    fprintf(stderr,"cannot create socket\n");
    return -1;
  }

  tcpnodelay(fd);
  if(tcpnumconnect(fd,ip,port) < 0){
    fprintf(stderr,"cannot connect to %X:%d\n",ip,port);
    return -1;
  }

  e->sockfd = fd;
	tcpgetpeer(fd,&(e->peerip),NULL);

  //@TODO: add login

  return fd;
}
Ejemplo n.º 19
0
void masterconn_connected(masterconn *eptr) {
    double now;

    now = monotonic_seconds();
    tcpnodelay(eptr->sock);
    eptr->mode = DATA;
    eptr->lastread = now;
    eptr->lastwrite = now;
    eptr->input_bytesleft = 8;
    eptr->input_startptr = eptr->input_hdr;
    eptr->input_end = 0;
    eptr->input_packet = NULL;
    eptr->inputhead = NULL;
    eptr->inputtail = &(eptr->inputhead);
    eptr->outputhead = NULL;
    eptr->outputtail = &(eptr->outputhead);

    masterconn_sendregister(eptr);
    if (lastlogversion==0) {
        masterconn_metadownloadinit();
    }
}
Ejemplo n.º 20
0
//initialize listen port
int masterconn_initlisten() {
        lsock = tcpsocket();
        if (lsock<0) {
                MFSLOG(LOG_ERR,"smtoma: socket error: %m");
                fprintf(msgfd,"shadow master <-> master module: can't create socket\n");
                return -1;
        }
        tcpnonblock(lsock);
        tcpnodelay(lsock);
        tcpreuseaddr(lsock);
        if (tcpsetacceptfilter(lsock)<0) {
                MFSLOG(LOG_NOTICE,"smtoma: can't set accept filter: %m");
        }
        if (tcpstrlisten(lsock,ListenHost,ListenPort,100)<0) {
                MFSLOG(LOG_ERR,"smtoma: listen  port:%s error: %m\n", ListenPort);
                fprintf(msgfd,"shadow master to master  module: can't listen on socket\n");
                return -1;
        }
        MFSLOG(LOG_NOTICE,"smtoma: listen on %s:%s",ListenHost,ListenPort);
        fprintf(msgfd,"slave <-> master module: listen on %s:%s\n",ListenHost,ListenPort);
	return 0;
}
Ejemplo n.º 21
0
int server()
{
    char buffer[1024];
    int ss = server_socket("127.0.0.1", "9991");
    if (ss < 0) {
        logging(LOG_ERROR, "socket error!");
        return -1;
    }
    int ns = tcptoaccept(ss, 100000);
    if (ns < 0) {
        logging(LOG_ERROR, "accept error!");
        return -1;
    }
    tcpnonblock(ns);
    tcpnodelay(ns);
    tcptoread(ns, buffer, 10, 3000);
    /*printf("read ok %d !!\n", n); */
    /*printf("read data: \n%s\n", buffer); */
    assert(strcmp("helloworl", buffer) == 0);
    tcpclose(ns);
    tcpclose(ss);
    return 0;
}
Ejemplo n.º 22
0
/* singleipconnect() connects to the given IP only, and it may return without
   having connected if used from the multi interface. */
static curl_socket_t
singleipconnect(struct connectdata *conn,
                const Curl_addrinfo *ai,
                long timeout_ms,
                bool *connected)
{
  char addr_buf[128];
  int rc;
  int error;
  bool isconnected;
  struct SessionHandle *data = conn->data;
  curl_socket_t sockfd;
  CURLcode res;

  sockfd = socket(ai->ai_family, conn->socktype, ai->ai_protocol);
  if (sockfd == CURL_SOCKET_BAD)
    return CURL_SOCKET_BAD;

  *connected = FALSE; /* default is not connected */

  Curl_printable_address(ai, addr_buf, sizeof(addr_buf));
  infof(data, "  Trying %s... ", addr_buf);

  if(data->set.tcp_nodelay)
    tcpnodelay(conn, sockfd);

  nosigpipe(conn, sockfd);

  if(data->set.fsockopt) {
    /* activate callback for setting socket options */
    error = data->set.fsockopt(data->set.sockopt_client,
                               sockfd,
                               CURLSOCKTYPE_IPCXN);
    if (error) {
      sclose(sockfd); /* close the socket and bail out */
      return CURL_SOCKET_BAD;
    }
  }

  /* possibly bind the local end to an IP, interface or port */
  res = bindlocal(conn, sockfd);
  if(res) {
    sclose(sockfd); /* close socket and bail out */
    return CURL_SOCKET_BAD;
  }

  /* set socket non-blocking */
  Curl_nonblock(sockfd, TRUE);

  /* Connect TCP sockets, bind UDP */
  if(conn->socktype == SOCK_STREAM)
    rc = connect(sockfd, ai->ai_addr, ai->ai_addrlen);
  else
    rc = 0;

  if(-1 == rc) {
    error = Curl_sockerrno();

    switch (error) {
    case EINPROGRESS:
    case EWOULDBLOCK:
#if defined(EAGAIN) && EAGAIN != EWOULDBLOCK
      /* On some platforms EAGAIN and EWOULDBLOCK are the
       * same value, and on others they are different, hence
       * the odd #if
       */
    case EAGAIN:
#endif
      rc = waitconnect(sockfd, timeout_ms);
      break;
    default:
      /* unknown error, fallthrough and try another address! */
      failf(data, "Failed to connect to %s: %s",
            addr_buf, Curl_strerror(conn,error));
      data->state.os_errno = error;
      break;
    }
  }

  /* The 'WAITCONN_TIMEOUT == rc' comes from the waitconnect(), and not from
     connect(). We can be sure of this since connect() cannot return 1. */
  if((WAITCONN_TIMEOUT == rc) &&
     (data->state.used_interface == Curl_if_multi)) {
    /* Timeout when running the multi interface */
    return sockfd;
  }

  isconnected = verifyconnect(sockfd, &error);

  if(!rc && isconnected) {
    /* we are connected, awesome! */
    *connected = TRUE; /* this is a true connect */
    infof(data, "connected\n");
    return sockfd;
  }
  else if(WAITCONN_TIMEOUT == rc)
    infof(data, "Timeout\n");
  else {
    data->state.os_errno = error;
    infof(data, "%s\n", Curl_strerror(conn, error));
  }

  /* connect failed or timed out */
  sclose(sockfd);

  return CURL_SOCKET_BAD;
}
Ejemplo n.º 23
0
/* singleipconnect() connects to the given IP only, and it may return without
   having connected if used from the multi interface. */
static curl_socket_t
singleipconnect(struct connectdata *conn,
                const Curl_addrinfo *ai,
                long timeout_ms,
                bool *connected)
{
    struct Curl_sockaddr_ex addr;
    char addr_buf[128];
    int rc;
    int error;
    bool isconnected;
    struct SessionHandle *data = conn->data;
    curl_socket_t sockfd;
    CURLcode res;
    const void *iptoprint;
    struct sockaddr_in * const sa4 = (void *)&addr.sa_addr;
#ifdef ENABLE_IPV6
    struct sockaddr_in6 * const sa6 = (void *)&addr.sa_addr;
#endif

    /*
     * The Curl_sockaddr_ex structure is basically libcurl's external API
     * curl_sockaddr structure with enough space available to directly hold
     * any protocol-specific address structures. The variable declared here
     * will be used to pass / receive data to/from the fopensocket callback
     * if this has been set, before that, it is initialized from parameters.
     */

    addr.family = ai->ai_family;
    addr.socktype = conn->socktype;
    addr.protocol = ai->ai_protocol;
    addr.addrlen = ai->ai_addrlen;

    if(addr.addrlen > sizeof(struct Curl_sockaddr_storage))
        addr.addrlen = sizeof(struct Curl_sockaddr_storage);
    memcpy(&addr.sa_addr, ai->ai_addr, addr.addrlen);

    *connected = FALSE; /* default is not connected */

    if(data->set.fopensocket)
        /*
         * If the opensocket callback is set, all the destination address
         * information is passed to the callback. Depending on this information the
         * callback may opt to abort the connection, this is indicated returning
         * CURL_SOCKET_BAD; otherwise it will return a not-connected socket. When
         * the callback returns a valid socket the destination address information
         * might have been changed and this 'new' address will actually be used
         * here to connect.
         */
        sockfd = data->set.fopensocket(data->set.opensocket_client,
                                       CURLSOCKTYPE_IPCXN,
                                       (struct curl_sockaddr *)&addr);
    else
        /* opensocket callback not set, so simply create the socket now */
        sockfd = socket(addr.family, addr.socktype, addr.protocol);

    if(sockfd == CURL_SOCKET_BAD)
        /* no socket, no connection */
        return CURL_SOCKET_BAD;

#if defined(ENABLE_IPV6) && defined(HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID)
    if (conn->scope && (addr.family == AF_INET6))
        sa6->sin6_scope_id = conn->scope;
#endif

    /* FIXME: do we have Curl_printable_address-like with struct sockaddr* as
       argument? */
#if defined(HAVE_SYS_UN_H) && defined(AF_UNIX)
    if(addr.family == AF_UNIX) {
        infof(data, "  Trying %s... ",
              ((const struct sockaddr_un*)(&addr.sa_addr))->sun_path);
        snprintf(data->info.ip, MAX_IPADR_LEN, "%s",
                 ((const struct sockaddr_un*)(&addr.sa_addr))->sun_path);
        strcpy(conn->ip_addr_str, data->info.ip);
    }
    else
#endif
    {
#ifdef ENABLE_IPV6
        if(addr.family == AF_INET6) {
            iptoprint = &sa6->sin6_addr;
            conn->bits.ipv6 = TRUE;
        }
        else
#endif
        {
            iptoprint = &sa4->sin_addr;
        }

        if(Curl_inet_ntop(addr.family, iptoprint, addr_buf,
                          sizeof(addr_buf)) != NULL) {
            infof(data, "  Trying %s... ", addr_buf);
            snprintf(data->info.ip, MAX_IPADR_LEN, "%s", addr_buf);
            strcpy(conn->ip_addr_str, data->info.ip);
        }
    }

    if(data->set.tcp_nodelay)
        tcpnodelay(conn, sockfd);

    nosigpipe(conn, sockfd);

    Curl_sndbufset(sockfd);

    if(data->set.fsockopt) {
        /* activate callback for setting socket options */
        error = data->set.fsockopt(data->set.sockopt_client,
                                   sockfd,
                                   CURLSOCKTYPE_IPCXN);
        if(error) {
            sclose(sockfd); /* close the socket and bail out */
            return CURL_SOCKET_BAD;
        }
    }

    /* possibly bind the local end to an IP, interface or port */
    res = bindlocal(conn, sockfd, addr.family);
    if(res) {
        sclose(sockfd); /* close socket and bail out */
        return CURL_SOCKET_BAD;
    }

    /* set socket non-blocking */
    curlx_nonblock(sockfd, TRUE);

    /* Connect TCP sockets, bind UDP */
    if(conn->socktype == SOCK_STREAM)
        rc = connect(sockfd, &addr.sa_addr, addr.addrlen);
    else
        rc = 0;

    if(-1 == rc) {
        error = SOCKERRNO;

        switch (error) {
        case EINPROGRESS:
        case EWOULDBLOCK:
#if defined(EAGAIN)
#if (EAGAIN) != (EWOULDBLOCK)
        /* On some platforms EAGAIN and EWOULDBLOCK are the
         * same value, and on others they are different, hence
         * the odd #if
         */
        case EAGAIN:
#endif
#endif
            rc = waitconnect(conn, sockfd, timeout_ms);
            break;
        default:
            /* unknown error, fallthrough and try another address! */
            failf(data, "Failed to connect to %s: %s",
                  addr_buf, Curl_strerror(conn,error));
            data->state.os_errno = error;
            break;
        }
    }

    /* The 'WAITCONN_TIMEOUT == rc' comes from the waitconnect(), and not from
       connect(). We can be sure of this since connect() cannot return 1. */
    if((WAITCONN_TIMEOUT == rc) &&
            (data->state.used_interface == Curl_if_multi)) {
        /* Timeout when running the multi interface */
        return sockfd;
    }

    isconnected = verifyconnect(sockfd, &error);

    if(!rc && isconnected) {
        /* we are connected, awesome! */
        *connected = TRUE; /* this is a true connect */
        infof(data, "connected\n");
        Curl_updateconninfo(conn, sockfd);
        return sockfd;
    }
    else if(WAITCONN_TIMEOUT == rc)
        infof(data, "Timeout\n");
    else {
        data->state.os_errno = error;
        infof(data, "%s\n", Curl_strerror(conn, error));
    }

    /* connect failed or timed out */
    sclose(sockfd);

    return CURL_SOCKET_BAD;
}
Ejemplo n.º 24
0
/*
 * singleipconnect()
 *
 * Note that even on connect fail it returns CURLE_OK, but with 'sock' set to
 * CURL_SOCKET_BAD. Other errors will however return proper errors.
 *
 * singleipconnect() connects to the given IP only, and it may return without
 * having connected.
 */
static CURLcode singleipconnect(struct connectdata *conn,
                                const Curl_addrinfo *ai,
                                curl_socket_t *sockp)
{
  struct Curl_sockaddr_ex addr;
  int rc;
  int error = 0;
  bool isconnected = FALSE;
  struct SessionHandle *data = conn->data;
  curl_socket_t sockfd;
  CURLcode result;
  char ipaddress[MAX_IPADR_LEN];
  long port;
  bool is_tcp;

  *sockp = CURL_SOCKET_BAD;

  result = Curl_socket(conn, ai, &addr, &sockfd);
  if(result)
    /* Failed to create the socket, but still return OK since we signal the
       lack of socket as well. This allows the parent function to keep looping
       over alternative addresses/socket families etc. */
    return CURLE_OK;

  /* store remote address and port used in this connection attempt */
  if(!getaddressinfo((struct sockaddr*)&addr.sa_addr,
                     ipaddress, &port)) {
    /* malformed address or bug in inet_ntop, try next address */
    error = ERRNO;
    failf(data, "sa_addr inet_ntop() failed with errno %d: %s",
          error, Curl_strerror(conn, error));
    Curl_closesocket(conn, sockfd);
    return CURLE_OK;
  }
  infof(data, "  Trying %s...\n", ipaddress);

  is_tcp = (addr.family == AF_INET || addr.family == AF_INET6) &&
           addr.socktype == SOCK_STREAM;
  if(is_tcp && data->set.tcp_nodelay)
    tcpnodelay(conn, sockfd);

  nosigpipe(conn, sockfd);

  Curl_sndbufset(sockfd);

  if(is_tcp && data->set.tcp_keepalive)
    tcpkeepalive(data, sockfd);

  if(data->set.fsockopt) {
    /* activate callback for setting socket options */
    error = data->set.fsockopt(data->set.sockopt_client,
                               sockfd,
                               CURLSOCKTYPE_IPCXN);

    if(error == CURL_SOCKOPT_ALREADY_CONNECTED)
      isconnected = TRUE;
    else if(error) {
      Curl_closesocket(conn, sockfd); /* close the socket and bail out */
      return CURLE_ABORTED_BY_CALLBACK;
    }
  }

  /* possibly bind the local end to an IP, interface or port */
  if(addr.family == AF_INET || addr.family == AF_INET6) {
    result = bindlocal(conn, sockfd, addr.family,
                       Curl_ipv6_scope((struct sockaddr*)&addr.sa_addr));
    if(result) {
      Curl_closesocket(conn, sockfd); /* close socket and bail out */
      if(result == CURLE_UNSUPPORTED_PROTOCOL) {
        /* The address family is not supported on this interface.
           We can continue trying addresses */
        return CURLE_COULDNT_CONNECT;
      }
      return result;
    }
  }

  /* set socket non-blocking */
  (void)curlx_nonblock(sockfd, TRUE);

  conn->connecttime = Curl_tvnow();
  if(conn->num_addr > 1)
    Curl_expire_latest(data, conn->timeoutms_per_addr);

  /* Connect TCP sockets, bind UDP */
  if(!isconnected && (conn->socktype == SOCK_STREAM)) {
    rc = connect(sockfd, &addr.sa_addr, addr.addrlen);
    if(-1 == rc)
      error = SOCKERRNO;
  }
  else {
    *sockp = sockfd;
    return CURLE_OK;
  }

#ifdef ENABLE_IPV6
  conn->bits.ipv6 = (addr.family == AF_INET6)?TRUE:FALSE;
#endif

  if(-1 == rc) {
    switch(error) {
    case EINPROGRESS:
    case EWOULDBLOCK:
#if defined(EAGAIN)
#if (EAGAIN) != (EWOULDBLOCK)
      /* On some platforms EAGAIN and EWOULDBLOCK are the
       * same value, and on others they are different, hence
       * the odd #if
       */
    case EAGAIN:
#endif
#endif
      result = CURLE_OK;
      break;

    default:
      /* unknown error, fallthrough and try another address! */
      infof(data, "Immediate connect fail for %s: %s\n",
            ipaddress, Curl_strerror(conn,error));
      data->state.os_errno = error;

      /* connect failed */
      Curl_closesocket(conn, sockfd);
      result = CURLE_COULDNT_CONNECT;
    }
  }

  if(!result)
    *sockp = sockfd;

  return result;
}
Ejemplo n.º 25
0
/*
 * singleipconnect()
 *
 * Note that even on connect fail it returns CURLE_OK, but with 'sock' set to
 * CURL_SOCKET_BAD. Other errors will however return proper errors.
 *
 * singleipconnect() connects to the given IP only, and it may return without
 * having connected if used from the multi interface.
 */
static CURLcode
singleipconnect(struct connectdata *conn,
                const Curl_addrinfo *ai,
                long timeout_ms,
                curl_socket_t *sockp,
                bool *connected)
{
  struct Curl_sockaddr_ex addr;
  int rc;
  int error = 0;
  bool isconnected = FALSE;
  struct SessionHandle *data = conn->data;
  curl_socket_t sockfd;
  CURLcode res = CURLE_OK;

  *sockp = CURL_SOCKET_BAD;
  *connected = FALSE; /* default is not connected */

  res = Curl_socket(conn, ai, &addr, &sockfd);
  if(res)
    /* Failed to create the socket, but still return OK since we signal the
       lack of socket as well. This allows the parent function to keep looping
       over alternative addresses/socket families etc. */
    return CURLE_OK;

  /* store remote address and port used in this connection attempt */
  if(!getaddressinfo((struct sockaddr*)&addr.sa_addr,
                     conn->primary_ip, &conn->primary_port)) {
    /* malformed address or bug in inet_ntop, try next address */
    error = ERRNO;
    failf(data, "sa_addr inet_ntop() failed with errno %d: %s",
          error, Curl_strerror(conn, error));
    Curl_closesocket(conn, sockfd);
    return CURLE_OK;
  }
  memcpy(conn->ip_addr_str, conn->primary_ip, MAX_IPADR_LEN);
  infof(data, "  Trying %s...\n", conn->ip_addr_str);

  Curl_persistconninfo(conn);

  if(data->set.tcp_nodelay)
    tcpnodelay(conn, sockfd);

  nosigpipe(conn, sockfd);

  Curl_sndbufset(sockfd);

  if(data->set.tcp_keepalive)
    tcpkeepalive(data, sockfd);

  if(data->set.fsockopt) {
    /* activate callback for setting socket options */
    error = data->set.fsockopt(data->set.sockopt_client,
                               sockfd,
                               CURLSOCKTYPE_IPCXN);

    if(error == CURL_SOCKOPT_ALREADY_CONNECTED)
      isconnected = TRUE;
    else if(error) {
      Curl_closesocket(conn, sockfd); /* close the socket and bail out */
      return CURLE_ABORTED_BY_CALLBACK;
    }
  }

  /* possibly bind the local end to an IP, interface or port */
  res = bindlocal(conn, sockfd, addr.family);
  if(res) {
    Curl_closesocket(conn, sockfd); /* close socket and bail out */
    return res;
  }

  /* set socket non-blocking */
  curlx_nonblock(sockfd, TRUE);

  /* Connect TCP sockets, bind UDP */
  if(!isconnected && (conn->socktype == SOCK_STREAM)) {
    rc = connect(sockfd, &addr.sa_addr, addr.addrlen);
    if(-1 == rc)
      error = SOCKERRNO;
    conn->connecttime = Curl_tvnow();
    if(conn->num_addr > 1)
      Curl_expire(data, conn->timeoutms_per_addr);
  }
  else
    rc = 0;

  if(-1 == rc) {
    switch (error) {
    case EINPROGRESS:
    case EWOULDBLOCK:
#if defined(EAGAIN)
#if (EAGAIN) != (EWOULDBLOCK)
      /* On some platforms EAGAIN and EWOULDBLOCK are the
       * same value, and on others they are different, hence
       * the odd #if
       */
    case EAGAIN:
#endif
#endif
      rc = waitconnect(conn, sockfd, timeout_ms);
      if(WAITCONN_ABORTED == rc) {
        Curl_closesocket(conn, sockfd);
        return CURLE_ABORTED_BY_CALLBACK;
      }
      break;
    default:
      /* unknown error, fallthrough and try another address! */
      failf(data, "Failed to connect to %s: %s",
            conn->ip_addr_str, Curl_strerror(conn,error));
      data->state.os_errno = error;
      break;
    }
  }

  /* The 'WAITCONN_TIMEOUT == rc' comes from the waitconnect(), and not from
     connect(). We can be sure of this since connect() cannot return 1. */
  if((WAITCONN_TIMEOUT == rc) &&
     (data->state.used_interface == Curl_if_multi)) {
    /* Timeout when running the multi interface */
    *sockp = sockfd;
    return CURLE_OK;
  }

  if(!isconnected)
    isconnected = verifyconnect(sockfd, &error);

  if(!rc && isconnected) {
    /* we are connected, awesome! */
    *connected = TRUE; /* this is a true connect */
    infof(data, "connected\n");
#ifdef ENABLE_IPV6
    conn->bits.ipv6 = (addr.family == AF_INET6)?TRUE:FALSE;
#endif

    Curl_updateconninfo(conn, sockfd);
    *sockp = sockfd;
    return CURLE_OK;
  }
  else if(WAITCONN_TIMEOUT == rc)
    infof(data, "Timeout\n");
  else {
    data->state.os_errno = error;
    infof(data, "%s\n", Curl_strerror(conn, error));
  }

  /* connect failed or timed out */
  Curl_closesocket(conn, sockfd);

  return CURLE_OK;
}
Ejemplo n.º 26
0
/* main working thread | glock:UNLOCKED */
void* write_worker(void *arg) {
	uint32_t z1,z2,z3;
	uint8_t *data;
	int fd;
	int i;
	struct pollfd pfd[2];
	uint32_t sent,rcvd;
	uint8_t recvbuff[21];
	uint8_t sendbuff[32];
#ifdef HAVE_WRITEV
	struct iovec siov[2];
#endif
	uint8_t pipebuff[1024];
	uint8_t *wptr;
	const uint8_t *rptr;

	uint32_t reccmd;
	uint32_t recleng;
	uint64_t recchunkid;
	uint32_t recwriteid;
	uint8_t recstatus;

#ifdef WORKER_DEBUG
	uint32_t partialblocks;
	uint32_t bytessent;
	char debugchain[200];
	uint32_t cl;
#endif

	const uint8_t *cp,*cpe;
	uint32_t chainip[10];
	uint16_t chainport[10];
	uint16_t chainelements;

	uint16_t chindx;
	uint32_t ip;
	uint16_t port;
	uint32_t srcip;
	uint64_t mfleng;
	uint64_t maxwroffset;
	uint64_t chunkid;
	uint32_t version;
	uint32_t nextwriteid;
	const uint8_t *chain;
	uint32_t chainsize;
	const uint8_t *csdata;
	uint32_t csdatasize;
	uint8_t westatus;
	uint8_t wrstatus;
	int status;
	uint8_t waitforstatus;
	uint8_t havedata;
	struct timeval start,now,lastrcvd,lrdiff;

	uint8_t cnt;

	inodedata *id;
	cblock *cb,*rcb;
//	inodedata *id;

	chainelements = 0;

	(void)arg;
	for (;;) {
		for (cnt=0 ; cnt<chainelements ; cnt++) {
			csdb_writedec(chainip[cnt],chainport[cnt]);
		}
		chainelements=0;

		// get next job
		queue_get(jqueue,&z1,&z2,&data,&z3);
		id = (inodedata*)data;

		pthread_mutex_lock(&glock);
		if (id->datachainhead) {
			chindx = id->datachainhead->chindx;
		} else {
			syslog(LOG_WARNING,"writeworker got inode with no data to write !!!");
			chindx = 0xFFFF;
			status = EINVAL;	// this should never happen, so status is not important - just anything
		}
		status = id->status;
		pthread_mutex_unlock(&glock);

		if (status) {
			write_job_end(id,status,0);
			continue;
		}

		// syslog(LOG_NOTICE,"file: %"PRIu32", index: %"PRIu16" - debug1",id->inode,chindx);
		// get chunk data from master
		wrstatus = fs_writechunk(id->inode,chindx,&mfleng,&chunkid,&version,&csdata,&csdatasize);
		if (wrstatus!=STATUS_OK) {
			syslog(LOG_WARNING,"file: %"PRIu32", index: %"PRIu16" - fs_writechunk returns status %d",id->inode,chindx,wrstatus);
			if (wrstatus!=ERROR_LOCKED) {
				if (wrstatus==ERROR_ENOENT) {
					write_job_end(id,EBADF,0);
				} else if (wrstatus==ERROR_QUOTA) {
					write_job_end(id,EDQUOT,0);
				} else if (wrstatus==ERROR_NOSPACE) {
					write_job_end(id,ENOSPC,0);
				} else {
					id->trycnt++;
					if (id->trycnt>=maxretries) {
						if (wrstatus==ERROR_NOCHUNKSERVERS) {
							write_job_end(id,ENOSPC,0);
						} else {
							write_job_end(id,EIO,0);
						}
					} else {
						write_delayed_enqueue(id,1+(id->trycnt<30)?(id->trycnt/3):10);
					}
				}
			} else {
				write_delayed_enqueue(id,1+(id->trycnt<30)?(id->trycnt/3):10);
			}
			continue;	// get next job
		}
		if (csdata==NULL || csdatasize==0) {
			syslog(LOG_WARNING,"file: %"PRIu32", index: %"PRIu16", chunk: %"PRIu64", version: %"PRIu32" - there are no valid copies",id->inode,chindx,chunkid,version);
			id->trycnt+=6;
			if (id->trycnt>=maxretries) {
				write_job_end(id,ENXIO,0);
			} else {
				write_delayed_enqueue(id,60);
			}
			continue;
		}
		cp = csdata;
		cpe = csdata+csdatasize;
		while (cp<cpe && chainelements<10) {
			chainip[chainelements] = get32bit(&cp);
			chainport[chainelements] = get16bit(&cp);
			csdb_writeinc(chainip[chainelements],chainport[chainelements]);
			chainelements++;
		}

		chain = csdata;
		ip = get32bit(&chain);
		port = get16bit(&chain);
		chainsize = csdatasize-6;
		gettimeofday(&start,NULL);

/*
		if (csdatasize>CSDATARESERVE) {
			csdatasize = CSDATARESERVE;
		}
		memcpy(wrec->csdata,csdata,csdatasize);
		wrec->csdatasize=csdatasize;
		while (csdatasize>=6) {
			tmpip = get32bit(&csdata);
			tmpport = get16bit(&csdata);
			csdatasize-=6;
			csdb_writeinc(tmpip,tmpport);
		}
*/

		// make connection to cs
		srcip = fs_getsrcip();
		cnt=5;
		while (cnt>0) {
			fd = tcpsocket();
			if (fd<0) {
				syslog(LOG_WARNING,"can't create tcp socket: %m");
				cnt=0;
			}
			if (srcip) {
				if (tcpnumbind(fd,srcip,0)<0) {
					syslog(LOG_WARNING,"can't bind socket to given ip: %m");
					tcpclose(fd);
					fd=-1;
					break;
				}
			}
			if (tcpnumtoconnect(fd,ip,port,200)<0) {
				cnt--;
				if (cnt==0) {
					syslog(LOG_WARNING,"can't connect to (%08"PRIX32":%"PRIu16"): %m",ip,port);
				}
				tcpclose(fd);
				fd=-1;
			} else {
				cnt=0;
			}
		}
		if (fd<0) {
			fs_writeend(chunkid,id->inode,0);
			id->trycnt++;
			if (id->trycnt>=maxretries) {
				write_job_end(id,EIO,0);
			} else {
				write_delayed_enqueue(id,1+(id->trycnt<30)?(id->trycnt/3):10);
			}
			continue;
		}
		if (tcpnodelay(fd)<0) {
			syslog(LOG_WARNING,"can't set TCP_NODELAY: %m");
		}

#ifdef WORKER_DEBUG
		partialblocks=0;
		bytessent=0;
#endif
		nextwriteid=1;

		pfd[0].fd = fd;
		pfd[1].fd = id->pipe[0];
		rcvd = 0;
		sent = 0;
		waitforstatus=1;
		havedata=1;
		wptr = sendbuff;
		put32bit(&wptr,CUTOCS_WRITE);
		put32bit(&wptr,12+chainsize);
		put64bit(&wptr,chunkid);
		put32bit(&wptr,version);
// debug:	syslog(LOG_NOTICE,"writeworker: init packet prepared");
		cb = NULL;

		status = 0;
		wrstatus = STATUS_OK;

		lastrcvd.tv_sec = 0;

		do {
			gettimeofday(&now,NULL);

			if (lastrcvd.tv_sec==0) {
				lastrcvd = now;
			} else {
				lrdiff = now;
				if (lrdiff.tv_usec<lastrcvd.tv_usec) {
					lrdiff.tv_sec--;
					lrdiff.tv_usec+=1000000;
				}
				lrdiff.tv_sec -= lastrcvd.tv_sec;
				lrdiff.tv_usec -= lastrcvd.tv_usec;
				if (lrdiff.tv_sec>=2) {
					syslog(LOG_WARNING,"file: %"PRIu32", index: %"PRIu16", chunk: %"PRIu64", version: %"PRIu32" - writeworker: connection with (%08"PRIX32":%"PRIu16") was timed out (unfinished writes: %"PRIu8"; try counter: %"PRIu32")",id->inode,chindx,chunkid,version,ip,port,waitforstatus,id->trycnt+1);
					break;
				}
			}

			if (now.tv_usec<start.tv_usec) {
				now.tv_sec--;
				now.tv_usec+=1000000;
			}
			now.tv_sec -= start.tv_sec;
			now.tv_usec -= start.tv_usec;

			if (havedata==0 && now.tv_sec<5 && waitforstatus<5) {
				pthread_mutex_lock(&glock);
				if (cb==NULL) {
					if (id->datachainhead) {
						if (id->datachainhead->to-id->datachainhead->from==65536 || waitforstatus<=1) {
							cb = id->datachainhead;
							havedata=1;
						}
					}
				} else {
					if (cb->next) {
						if (cb->next->chindx==chindx) {
							if (cb->next->to-cb->next->from==65536 || waitforstatus<=1) {
								cb = cb->next;
								havedata=1;
							}
						}
					} else {
						id->waitingworker=1;
					}
				}
				if (havedata==1) {
					cb->writeid = nextwriteid++;
// debug:				syslog(LOG_NOTICE,"writeworker: data packet prepared (writeid:%"PRIu32",pos:%"PRIu16")",cb->writeid,cb->pos);
					waitforstatus++;
					wptr = sendbuff;
					put32bit(&wptr,CUTOCS_WRITE_DATA);
					put32bit(&wptr,24+(cb->to-cb->from));
					put64bit(&wptr,chunkid);
					put32bit(&wptr,cb->writeid);
					put16bit(&wptr,cb->pos);
					put16bit(&wptr,cb->from);
					put32bit(&wptr,cb->to-cb->from);
					put32bit(&wptr,mycrc32(0,cb->data+cb->from,cb->to-cb->from));
#ifdef WORKER_DEBUG
					if (cb->to-cb->from<65536) {
						partialblocks++;
					}
					bytessent+=(cb->to-cb->from);
#endif
					sent=0;
				}
				pthread_mutex_unlock(&glock);
			}

			pfd[0].events = POLLIN | (havedata?POLLOUT:0);
			pfd[0].revents = 0;
			pfd[1].events = POLLIN;
			pfd[1].revents = 0;
			if (poll(pfd,2,100)<0) { /* correct timeout - in msec */
				syslog(LOG_WARNING,"writeworker: poll error: %m");
				status=EIO;
				break;
			}
			if (pfd[1].revents&POLLIN) {	// used just to break poll - so just read all data from pipe to empty it
				i = read(id->pipe[0],pipebuff,1024);
			}
			if (pfd[0].revents&POLLIN) {
				i = read(fd,recvbuff+rcvd,21-rcvd);
				if (i==0) { 	// connection reset by peer ,读取文件头错误
					syslog(LOG_WARNING,"file: %"PRIu32", index: %"PRIu16", chunk: %"PRIu64", version: %"PRIu32" - writeworker: connection with (%08"PRIX32":%"PRIu16") was reset by peer (unfinished writes: %"PRIu8"; try counter: %"PRIu32")",id->inode,chindx,chunkid,version,ip,port,waitforstatus,id->trycnt+1);
					status=EIO;
					break;
				}
				gettimeofday(&lastrcvd,NULL);
				rcvd+=i;
				if (rcvd==21) {
					rptr = recvbuff;
					reccmd = get32bit(&rptr);
					recleng = get32bit(&rptr);
					recchunkid = get64bit(&rptr);
					recwriteid = get32bit(&rptr);
					recstatus = get8bit(&rptr);
					if (reccmd!=CSTOCU_WRITE_STATUS ||  recleng!=13) {
						syslog(LOG_WARNING,"writeworker: got unrecognized packet from chunkserver (cmd:%"PRIu32",leng:%"PRIu32")",reccmd,recleng);
						status=EIO;
						break;
					}
					if (recchunkid!=chunkid) {
						syslog(LOG_WARNING,"writeworker: got unexpected packet (expected chunkdid:%"PRIu64",packet chunkid:%"PRIu64")",chunkid,recchunkid);
						status=EIO;
						break;
					}
					if (recstatus!=STATUS_OK) {
						syslog(LOG_WARNING,"writeworker: write error: %"PRIu8,recstatus);
						wrstatus=recstatus;
						break;
					}
// debug:				syslog(LOG_NOTICE,"writeworker: received status ok for writeid:%"PRIu32,recwriteid);
					if (recwriteid>0) {
						pthread_mutex_lock(&glock);
						for (rcb = id->datachainhead ; rcb && rcb->writeid!=recwriteid ; rcb=rcb->next) {}
						if (rcb==NULL) {
							syslog(LOG_WARNING,"writeworker: got unexpected status (writeid:%"PRIu32")",recwriteid);
							pthread_mutex_unlock(&glock);
							status=EIO;
							break;
						}
						if (rcb==cb) {	// current block,cb为当前块儿指针
// debug:						syslog(LOG_NOTICE,"writeworker: received status for current block");
							if (havedata) {	// got status ok before all data had been sent - error
								syslog(LOG_WARNING,"writeworker: got status OK before all data have been sent");
								pthread_mutex_unlock(&glock);
								status=EIO;
								break;
							} else {
								cb = NULL;
							}
						}
						if (rcb->prev) {//将rcb所指块儿从链表中取出
							rcb->prev->next = rcb->next;
						} else {
							id->datachainhead = rcb->next;
						}
						if (rcb->next) {
							rcb->next->prev = rcb->prev;
						} else {
							id->datachaintail = rcb->prev;
						}
						maxwroffset = (((uint64_t)(chindx))<<26)+(((uint32_t)(rcb->pos))<<16)+rcb->to;
						if (maxwroffset>mfleng) {
							mfleng=maxwroffset;
						}
						write_cb_release(rcb);//
						id->cacheblocks--;
						if (id->cachewaiting>0) {
							pthread_cond_broadcast(&(id->cachecond));
						}
						pthread_mutex_unlock(&glock);
					}
					waitforstatus--;
					rcvd=0;
				}
			}
			if (havedata && (pfd[0].revents&POLLOUT)) {
				if (cb==NULL) {	// havedata==1 && cb==NULL means sending first packet (CUTOCS_WRITE)
					if (sent<20) {
#ifdef HAVE_WRITEV                //将多个数据存储在一起,将驻留在两个或更多的不连接的缓冲区中的数据一次写出去
						if (chainsize>0) {
							siov[0].iov_base = sendbuff+sent;
							siov[0].iov_len = 20-sent;
							siov[1].iov_base = (char*)chain;	// discard const (safe - because it's used in writev)
							siov[1].iov_len = chainsize;
							i = writev(fd,siov,2);
						} else {
#endif
							i = write(fd,sendbuff+sent,20-sent);
#ifdef HAVE_WRITEV
						}
#endif
					} else {
						i = write(fd,chain+(sent-20),chainsize-(sent-20));
					}
					if (i<0) {
						syslog(LOG_WARNING,"file: %"PRIu32", index: %"PRIu16", chunk: %"PRIu64", version: %"PRIu32" - writeworker: connection with (%08"PRIX32":%"PRIu16") was reset by peer (unfinished writes: %"PRIu8"; try counter: %"PRIu32")",id->inode,chindx,chunkid,version,ip,port,waitforstatus,id->trycnt+1);
						status=EIO;
						break;
					}
					sent+=i;
					if (sent==20+chainsize) {
						havedata=0;
					}
				} else {
					if (sent<32) {
#ifdef HAVE_WRITEV                
						siov[0].iov_base = sendbuff+sent;
						siov[0].iov_len = 32-sent;
						siov[1].iov_base = cb->data+cb->from;
						siov[1].iov_len = cb->to-cb->from;
						i = writev(fd,siov,2);
#else
						i = write(fd,sendbuff+sent,32-sent);
#endif
					} else {
						i = write(fd,cb->data+cb->from+(sent-32),cb->to-cb->from-(sent-32));
					}
					if (i<0) {
						syslog(LOG_WARNING,"file: %"PRIu32", index: %"PRIu16", chunk: %"PRIu64", version: %"PRIu32" - writeworker: connection with (%08"PRIX32":%"PRIu16") was reset by peer (unfinished writes: %"PRIu8"; try counter: %"PRIu32")",id->inode,chindx,chunkid,version,ip,port,waitforstatus,id->trycnt+1);
						status=EIO;
						break;
					}
					sent+=i;
					if (sent==32+cb->to-cb->from) {
						havedata=0;
					}
				}
			}
		} while (waitforstatus>0 && now.tv_sec<10);////////////////////


		id->waitingworker=0;

		tcpclose(fd);

#ifdef WORKER_DEBUG
		gettimeofday(&now,NULL);
		if (now.tv_usec<start.tv_usec) {
			now.tv_sec--;
			now.tv_usec+=1000000;
		}
		now.tv_sec -= start.tv_sec;
		now.tv_usec -= start.tv_usec;

		cl=0;
		for (cnt=0 ; cnt<chainelements ; cnt++) {
			cl+=snprintf(debugchain+cl,200-cl,"%u.%u.%u.%u:%u->",(chainip[cnt]>>24)&255,(chainip[cnt]>>16)&255,(chainip[cnt]>>8)&255,chainip[cnt]&255,chainport[cnt]);
		}
		if (cl>=2) {
			debugchain[cl-2]='\0';
		}
		syslog(LOG_NOTICE,"worker %lu sent %"PRIu32" blocks (%"PRIu32" partial) of chunk %016"PRIX64"_%08"PRIX32", received status for %"PRIu32" blocks (%"PRIu32" lost), bw: %.6lfMB ( %"PRIu32" B / %.0lf us ), chain: %s",(unsigned long)arg,nextwriteid-1,partialblocks,chunkid,version,nextwriteid-1-waitforstatus,waitforstatus,(double)bytessent/((double)(now.tv_sec)*1000000+(double)(now.tv_usec)),bytessent,((double)(now.tv_sec)*1000000+(double)(now.tv_usec)),debugchain);
#endif

		for (cnt=0 ; cnt<10 ; cnt++) {
			westatus = fs_writeend(chunkid,id->inode,mfleng);
			if (westatus!=STATUS_OK) {
				usleep(100000+(10000<<cnt));
			} else {
				break;
			}
		}

		if (westatus!=STATUS_OK) {
			write_job_end(id,ENXIO,0);
		} else if (status!=0 || wrstatus!=STATUS_OK) {
			if (wrstatus!=STATUS_OK) {	// convert MFS status to OS errno
				if (wrstatus==ERROR_NOSPACE) {
					status=ENOSPC;
				} else {
					status=EIO;
				}
			}
			id->trycnt++;
			if (id->trycnt>=maxretries) {
				write_job_end(id,status,0);
			} else {
				write_job_end(id,0,1+(id->trycnt<30)?(id->trycnt/3):10);
			}
		} else {
			read_inode_ops(id->inode);
			write_job_end(id,0,0);
		}
	}
}
Ejemplo n.º 27
0
/* srcs: srccnt * (chunkid:64 version:32 ip:32 port:16) */
uint8_t replicate(uint64_t chunkid,uint32_t version,const uint32_t xormasks[4],uint8_t srccnt,const uint8_t *srcs) {
	replication r;
	uint8_t status,i,j,vbuffs,first;
	uint16_t b,blocks;
	uint32_t xcrc[4],crc;
	uint32_t codeindex,codeword;
	uint8_t *wptr;
	const uint8_t *rptr;
	int s;

	if (srccnt==0) {
		return ERROR_EINVAL;
	}

//	syslog(LOG_NOTICE,"replication begin (chunkid:%08"PRIX64",version:%04"PRIX32",srccnt:%"PRIu8")",chunkid,version,srccnt);

	pthread_mutex_lock(&statslock);
	stats_repl++;
	pthread_mutex_unlock(&statslock);

// init replication structure
	r.chunkid = chunkid;
	r.version = version;
	r.srccnt = 0;
	r.created = 0;
	r.opened = 0;
	r.fds = malloc(sizeof(struct pollfd)*srccnt);
	passert(r.fds);
	r.repsources = malloc(sizeof(repsrc)*srccnt);
	passert(r.repsources);
	if (srccnt>1) {
		r.xorbuff = malloc(MFSBLOCKSIZE+4);
		passert(r.xorbuff);
	} else {
		r.xorbuff = NULL;
	}
// create chunk
	status = hdd_create(chunkid,0);
	if (status!=STATUS_OK) {
		syslog(LOG_NOTICE,"replicator: hdd_create status: %s",mfsstrerr(status));
		rep_cleanup(&r);
		return status;
	}
	r.created = 1;
// init sources
	r.srccnt = srccnt;
	for (i=0 ; i<srccnt ; i++) {
		r.repsources[i].chunkid = get64bit(&srcs);
		r.repsources[i].version = get32bit(&srcs);
		r.repsources[i].ip = get32bit(&srcs);
		r.repsources[i].port = get16bit(&srcs);
		r.repsources[i].sock = -1;
		r.repsources[i].packet = NULL;
	}
// connect
	for (i=0 ; i<srccnt ; i++) {
		s = tcpsocket();
		if (s<0) {
			mfs_errlog_silent(LOG_NOTICE,"replicator: socket error");
			rep_cleanup(&r);
			return ERROR_CANTCONNECT;
		}
		r.repsources[i].sock = s;
		r.fds[i].fd = s;
		if (tcpnonblock(s)<0) {
			mfs_errlog_silent(LOG_NOTICE,"replicator: nonblock error");
			rep_cleanup(&r);
			return ERROR_CANTCONNECT;
		}
		s = tcpnumconnect(s,r.repsources[i].ip,r.repsources[i].port);
		if (s<0) {
			mfs_errlog_silent(LOG_NOTICE,"replicator: connect error");
			rep_cleanup(&r);
			return ERROR_CANTCONNECT;
		}
		if (s==0) {
			r.repsources[i].mode = IDLE;
		} else {
			r.repsources[i].mode = CONNECTING;
		}
	}
	if (rep_wait_for_connection(&r,CONNMSECTO)<0) {
		rep_cleanup(&r);
		return ERROR_CANTCONNECT;
	}
// disable Nagle
	for (i=0 ; i<srccnt ; i++) {
		tcpnodelay(r.repsources[i].sock);
	}
// open chunk
	status = hdd_open(chunkid,0);
	if (status!=STATUS_OK) {
		syslog(LOG_NOTICE,"replicator: hdd_open status: %s",mfsstrerr(status));
		rep_cleanup(&r);
		return status;
	}
	r.opened = 1;
// get block numbers
	for (i=0 ; i<srccnt ; i++) {
		wptr = rep_create_packet(r.repsources+i,ANTOCS_GET_CHUNK_BLOCKS,8+4);
		if (wptr==NULL) {
			syslog(LOG_NOTICE,"replicator: out of memory");
			rep_cleanup(&r);
			return ERROR_OUTOFMEMORY;
		}
		put64bit(&wptr,r.repsources[i].chunkid);
		put32bit(&wptr,r.repsources[i].version);
	}
// send packet
	if (rep_send_all_packets(&r,SENDMSECTO)<0) {
		rep_cleanup(&r);
		return ERROR_DISCONNECTED;
	}
// receive answers
	for (i=0 ; i<srccnt ; i++) {
		r.repsources[i].mode = HEADER;
		r.repsources[i].startptr = r.repsources[i].hdrbuff;
		r.repsources[i].bytesleft = 8;
	}
	if (rep_receive_all_packets(&r,RECVMSECTO)<0) {
		rep_cleanup(&r);
		return ERROR_DISCONNECTED;
	}
// get # of blocks
	blocks = 0;
	for (i=0 ; i<srccnt ; i++) {
		uint32_t type,size;
		uint64_t pchid;
		uint32_t pver;
		uint16_t pblocks;
		uint8_t pstatus;
		uint32_t ip;
		rptr = r.repsources[i].hdrbuff;
		type = get32bit(&rptr);
		size = get32bit(&rptr);
		rptr = r.repsources[i].packet;
		ip = r.repsources[i].ip;
		if (rptr==NULL || type!=CSTOAN_CHUNK_BLOCKS || size!=15) {
			syslog(LOG_WARNING,"replicator,get # of blocks: got wrong answer (type:0x%08"PRIX32"/size:0x%08"PRIX32") from (%u.%u.%u.%u:%04"PRIX16")",type,size,(ip>>24)&0xFF,(ip>>16)&0xFF,(ip>>8)&0xFF,ip&0xFF,r.repsources[i].port);
			rep_cleanup(&r);
			return ERROR_DISCONNECTED;
		}
		pchid = get64bit(&rptr);
		pver = get32bit(&rptr);
		pblocks = get16bit(&rptr);
		pstatus = get8bit(&rptr);
		if (pchid!=r.repsources[i].chunkid) {
			syslog(LOG_WARNING,"replicator,get # of blocks: got wrong answer (chunk_status:chunkid:%"PRIX64"/%"PRIX64") from (%u.%u.%u.%u:%04"PRIX16")",pchid,r.repsources[i].chunkid,(ip>>24)&0xFF,(ip>>16)&0xFF,(ip>>8)&0xFF,ip&0xFF,r.repsources[i].port);
			rep_cleanup(&r);
			return ERROR_WRONGCHUNKID;
		}
Ejemplo n.º 28
0
void matomlserv_serve(struct pollfd *pdesc) {
	uint32_t now=main_time();
	matomlserventry *eptr,**kptr;
	packetstruct *pptr,*paptr;
	int ns;
	static uint64_t lastaction = 0;
	uint64_t unow;
	uint32_t timeoutadd;

	if (lastaction==0) {
		lastaction = main_precise_utime();
	}

	if (lsockpdescpos>=0 && (pdesc[lsockpdescpos].revents & POLLIN)) {
		ns=tcpaccept(lsock);
		if (ns<0) {
			mfs_errlog_silent(LOG_NOTICE,"Master<->ML socket: accept error");
		} else {
			tcpnonblock(ns);
			tcpnodelay(ns);
			eptr = malloc(sizeof(matomlserventry));
			passert(eptr);
			eptr->next = matomlservhead;
			matomlservhead = eptr;
			eptr->sock = ns;
			eptr->pdescpos = -1;
			eptr->mode = HEADER;
			eptr->lastread = now;
			eptr->lastwrite = now;
			eptr->inputpacket.next = NULL;
			eptr->inputpacket.bytesleft = 8;
			eptr->inputpacket.startptr = eptr->hdrbuff;
			eptr->inputpacket.packet = NULL;
			eptr->outputhead = NULL;
			eptr->outputtail = &(eptr->outputhead);
			eptr->timeout = 10;

			tcpgetpeer(eptr->sock,&(eptr->servip),NULL);
			eptr->servstrip = matomlserv_makestrip(eptr->servip);
			eptr->version=0;
			eptr->metafd=-1;
			eptr->chain1fd=-1;
			eptr->chain2fd=-1;
            eptr->logindex=-1;
            eptr->logf=NULL;
            eptr->currentversion=0;
		}
	}

// read
	for (eptr=matomlservhead ; eptr ; eptr=eptr->next) {
		if (eptr->pdescpos>=0) {
			if (pdesc[eptr->pdescpos].revents & (POLLERR|POLLHUP)) {
				eptr->mode = KILL;
			}
			if ((pdesc[eptr->pdescpos].revents & POLLIN) && eptr->mode!=KILL) {
				eptr->lastread = now;
				matomlserv_read(eptr);
			}
		}
	}

// timeout fix
	unow = main_precise_utime();
	timeoutadd = (unow-lastaction)/1000000;
	if (timeoutadd) {
		for (eptr=matomlservhead ; eptr ; eptr=eptr->next) {
			eptr->lastread += timeoutadd;
		}
	}
	lastaction = unow;

// write
	for (eptr=matomlservhead ; eptr ; eptr=eptr->next) {
		if ((uint32_t)(eptr->lastwrite+(eptr->timeout/3))<(uint32_t)now && eptr->outputhead==NULL) {
			matomlserv_createpacket(eptr,ANTOAN_NOP,0);
		}
		if (eptr->pdescpos>=0) {
			if ((((pdesc[eptr->pdescpos].events & POLLOUT)==0 && (eptr->outputhead)) || (pdesc[eptr->pdescpos].revents & POLLOUT)) && eptr->mode!=KILL) {
				eptr->lastwrite = now;
				matomlserv_write(eptr);
			}
            if (eptr->mode!=KILL && eptr->logf && eptr->outputhead==NULL) {
                matomlserv_send_old_changes(eptr, eptr->currentversion);
            }
		}
		if ((uint32_t)(eptr->lastread+eptr->timeout)<(uint32_t)now) {
			eptr->mode = KILL;
		}
	}

// close
	kptr = &matomlservhead;
	while ((eptr=*kptr)) {
		if (eptr->mode == KILL) {
			matomlserv_beforeclose(eptr);
			tcpclose(eptr->sock);
			if (eptr->inputpacket.packet) {
				free(eptr->inputpacket.packet);
			}
			pptr = eptr->outputhead;
			while (pptr) {
				if (pptr->packet) {
					free(pptr->packet);
				}
				paptr = pptr;
				pptr = pptr->next;
				free(paptr);
			}
			if (eptr->servstrip) {
				free(eptr->servstrip);
			}
			*kptr = eptr->next;
			free(eptr);
		} else {
			kptr = &(eptr->next);
		}
	}
}
Ejemplo n.º 29
0
/*
 * singleipconnect()
 *
 * Note that even on connect fail it returns CURLE_OK, but with 'sock' set to
 * CURL_SOCKET_BAD. Other errors will however return proper errors.
 *
 * singleipconnect() connects to the given IP only, and it may return without
 * having connected if used from the multi interface.
 */
static CURLcode
singleipconnect(struct connectdata *conn,
                const Curl_addrinfo *ai,
                long timeout_ms,
                curl_socket_t *sockp,
                bool *connected)
{
  struct Curl_sockaddr_ex addr;
  int rc;
  int error;
  bool isconnected = FALSE;
  struct SessionHandle *data = conn->data;
  curl_socket_t sockfd;
  CURLcode res = CURLE_OK;
#if defined(ENABLE_IPV6) && defined(HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID)
  struct sockaddr_in6 * const sa6 = (void *)&addr.sa_addr;
#endif

  *sockp = CURL_SOCKET_BAD;

  /*
   * The Curl_sockaddr_ex structure is basically libcurl's external API
   * curl_sockaddr structure with enough space available to directly hold
   * any protocol-specific address structures. The variable declared here
   * will be used to pass / receive data to/from the fopensocket callback
   * if this has been set, before that, it is initialized from parameters.
   */

  addr.family = ai->ai_family;
  addr.socktype = conn->socktype;
  addr.protocol = conn->socktype==SOCK_DGRAM?IPPROTO_UDP:ai->ai_protocol;
  addr.addrlen = ai->ai_addrlen;

  if(addr.addrlen > sizeof(struct Curl_sockaddr_storage))
     addr.addrlen = sizeof(struct Curl_sockaddr_storage);
  memcpy(&addr.sa_addr, ai->ai_addr, addr.addrlen);

  *connected = FALSE; /* default is not connected */

  if(data->set.fopensocket)
   /*
    * If the opensocket callback is set, all the destination address
    * information is passed to the callback. Depending on this information the
    * callback may opt to abort the connection, this is indicated returning
    * CURL_SOCKET_BAD; otherwise it will return a not-connected socket. When
    * the callback returns a valid socket the destination address information
    * might have been changed and this 'new' address will actually be used
    * here to connect.
    */
    sockfd = data->set.fopensocket(data->set.opensocket_client,
                                   CURLSOCKTYPE_IPCXN,
                                   (struct curl_sockaddr *)&addr);
  else
    /* opensocket callback not set, so simply create the socket now */
    sockfd = socket(addr.family, addr.socktype, addr.protocol);

  if(sockfd == CURL_SOCKET_BAD)
    /* no socket, no connection */
    return CURLE_OK;

#if defined(ENABLE_IPV6) && defined(HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID)
  if (conn->scope && (addr.family == AF_INET6))
    sa6->sin6_scope_id = conn->scope;
#endif

  /* store remote address and port used in this connection attempt */
  if(!getaddressinfo((struct sockaddr*)&addr.sa_addr,
                     conn->primary_ip, &conn->primary_port)) {
    /* malformed address or bug in inet_ntop, try next address */
    error = ERRNO;
    failf(data, "sa_addr inet_ntop() failed with errno %d: %s",
          error, Curl_strerror(conn, error));
    sclose(sockfd);
    return CURLE_OK;
  }
  memcpy(conn->ip_addr_str, conn->primary_ip, MAX_IPADR_LEN);
  infof(data, "  Trying %s... ", conn->ip_addr_str);

  Curl_persistconninfo(conn);

#ifdef ENABLE_IPV6
  if(addr.family == AF_INET6)
    conn->bits.ipv6 = TRUE;
#endif

  if(data->set.tcp_nodelay)
    tcpnodelay(conn, sockfd);

  nosigpipe(conn, sockfd);

  Curl_sndbufset(sockfd);

  if(data->set.fsockopt) {
    /* activate callback for setting socket options */
    error = data->set.fsockopt(data->set.sockopt_client,
                               sockfd,
                               CURLSOCKTYPE_IPCXN);

    if(error == CURL_SOCKOPT_ALREADY_CONNECTED)
      isconnected = TRUE;
    else if(error) {
      sclose(sockfd); /* close the socket and bail out */
      return CURLE_ABORTED_BY_CALLBACK;
    }
  }

  /* possibly bind the local end to an IP, interface or port */
  res = bindlocal(conn, sockfd, addr.family);
  if(res) {
    sclose(sockfd); /* close socket and bail out */
    return res;
  }

  /* set socket non-blocking */
  curlx_nonblock(sockfd, TRUE);

  /* Connect TCP sockets, bind UDP */
  if(!isconnected && (conn->socktype == SOCK_STREAM)) {
    rc = connect(sockfd, &addr.sa_addr, addr.addrlen);
    conn->connecttime = Curl_tvnow();
    if(conn->num_addr > 1)
      Curl_expire(data, conn->timeoutms_per_addr);
  }
  else
    rc = 0;

  if(-1 == rc) {
    error = SOCKERRNO;

    switch (error) {
    case EINPROGRESS:
    case EWOULDBLOCK:
#if defined(EAGAIN)
#if (EAGAIN) != (EWOULDBLOCK)
      /* On some platforms EAGAIN and EWOULDBLOCK are the
       * same value, and on others they are different, hence
       * the odd #if
       */
    case EAGAIN:
#endif
#endif
      rc = waitconnect(conn, sockfd, timeout_ms);
      if(WAITCONN_ABORTED == rc) {
        sclose(sockfd);
        return CURLE_ABORTED_BY_CALLBACK;
      }
      break;
    default:
      /* unknown error, fallthrough and try another address! */
      failf(data, "Failed to connect to %s: %s",
            conn->ip_addr_str, Curl_strerror(conn,error));
      data->state.os_errno = error;
      break;
    }
  }

  /* The 'WAITCONN_TIMEOUT == rc' comes from the waitconnect(), and not from
     connect(). We can be sure of this since connect() cannot return 1. */
  if((WAITCONN_TIMEOUT == rc) &&
     (data->state.used_interface == Curl_if_multi)) {
    /* Timeout when running the multi interface */
    *sockp = sockfd;
    return CURLE_OK;
  }

  if(!isconnected)
    isconnected = verifyconnect(sockfd, &error);

  if(!rc && isconnected) {
    /* we are connected, awesome! */
    *connected = TRUE; /* this is a true connect */
    infof(data, "connected\n");
    Curl_updateconninfo(conn, sockfd);
    *sockp = sockfd;
    return CURLE_OK;
  }
  else if(WAITCONN_TIMEOUT == rc)
    infof(data, "Timeout\n");
  else {
    data->state.os_errno = error;
    infof(data, "%s\n", Curl_strerror(conn, error));
  }

  /* connect failed or timed out */
  sclose(sockfd);

  return CURLE_OK;
}
Ejemplo n.º 30
0
void masterconn_serve(int epoll_fd,int count,struct epoll_event *pdesc) {
	//uint32_t now=main_time();
	serventry *weptr = NULL,*eptr = NULL;
	int ns;
	int ret;
       struct epoll_event ev;

	if(ismaster()) {
		return;
	}
	
	weptr = (serventry *)pdesc[count].data.ptr;
	if ((weptr->listen_sock == 1) && (pdesc[count].events & EPOLLIN) && (weptr->mode != KILL)) {
		ns = tcpaccept(lsock);
		if (ns<0) {
                        MFSLOG(LOG_INFO,"master sync thread<->shadow master socket: accept error: %m");
                } else {
                        tcpnonblock(ns);
                        tcpnodelay(ns);
                        master_serve = (serventry *)malloc(sizeof(serventry));
			eptr = master_serve;
                        eptr->sock = ns;
                        eptr->mode = HEADER;
                        eptr->lastread = eptr->lastwrite = get_current_time();                 
        		eptr->inputpacket.next = NULL;
        		eptr->inputpacket.bytesleft = 8;
        		eptr->inputpacket.startptr = eptr->hdrbuff;
        		eptr->inputpacket.packet = NULL;
			eptr->outputhead = NULL;
        		eptr->outputtail = &(eptr->outputhead);

			eptr->downloading = 0;
			eptr->metafd=-1;
                        eptr->logfd=NULL;

			eptr->listen_sock = 0;
                        eptr->connection = 3;
			
			ev.data.ptr = eptr;
                        ev.events = EPOLLIN;
                        ret = epoll_ctl(epoll_fd,EPOLL_CTL_ADD,ns,&ev);
			if (ret < 0) {
				MFSLOG(LOG_NOTICE,"add epoll fail");
			}
		}
	}
	if (weptr->listen_sock == 0) {
		if (weptr->mode == CONNECTING) {
			if (pdesc[count].events & (EPOLLHUP | EPOLLERR)) {
				masterconn_connecttest(weptr);
			}
			if (pdesc[count].events & EPOLLOUT) {
				masterconn_connecttest(weptr);
			}
		} else {	
			if ((pdesc[count].events & (EPOLLHUP | EPOLLERR)) && (weptr->mode != KILL)) {
				MFSLOG(LOG_NOTICE, "set to NULL");
				weptr->mode = KILL;
			}
			if ((weptr->mode==HEADER || weptr->mode==DATA) && (pdesc[count].events & EPOLLIN)) { // FD_ISSET(eptr->sock,rset)) {
				masterconn_read(weptr);
				weptr->lastread = get_current_time();				
			}
			if ((weptr->mode==HEADER || weptr->mode==DATA) && (pdesc[count].events & EPOLLOUT)) { // FD_ISSET(eptr->sock,wset)) {
				masterconn_write(weptr);
				weptr->lastwrite = get_current_time();				
			}
			if ((weptr->mode==HEADER || weptr->mode==DATA) && weptr->lastread+Timeout<get_current_time()) {
				MFSLOG(LOG_NOTICE, "set to NULL");
				weptr->mode = KILL;
			}
			if ((weptr->mode==HEADER || weptr->mode==DATA) && weptr->lastwrite+5<get_current_time()
				&& weptr->outputhead==NULL) {
				masterconn_createpacket(weptr,ANTOAN_NOP,0);
			}
		}
	}
}