Ejemplo n.º 1
0
static void test_tcp_client(void)
{
	int sd;
	int re;
	struct sockaddr_in sa;

	printf("[tcp(client)] start\n");

	sd = so_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	DEBUG_PRINT(("so_socket = %d(%d, %d)\n", sd, MERCD(sd), SERCD(sd)));
	if ( sd < 0 ) {
		goto error2;
	}

	bzero(&sa, sizeof sa);
	sa.sin_family = AF_INET;
	sa.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
	sa.sin_port = htons(12345);
	re = so_connect(sd, (struct sockaddr*)&sa, sizeof sa);
	printf("so_connect = %d(%d, %d)\n", re, MERCD(re), SERCD(re));
	if ( re < 0 ) {
		goto error2;
	}

	re = so_write(sd, "1234", 4);
	DEBUG_PRINT(("so_write = %d(%d, %d)\n", re, MERCD(re), SERCD(re)));
	if ( re < 0 ) {
		goto error2;
	}

	re = so_send(sd, "a", 1, MSG_OOB);
	DEBUG_PRINT(("so_send = %d(%d, %d)\n", re, MERCD(re), SERCD(re)));
	if ( re < 0 ) {
		goto error2;
	}

	so_close(sd);

	tk_wai_sem(semid2, 1, TMO_FEVR);
	re = so_break(server_tskid);
	DEBUG_PRINT(("so_break = %d(%d, %d)\n", re, MERCD(re), SERCD(re)));
	if ( re < 0 ) {
		goto error2;
	}

	printf("[tcp(client)] OK\n");
	return;

error2:
	if ( sd > 0 ) {
		so_close(sd);
	}
	so_break(server_tskid);
	printf("[tcp(client)] FAILED\n");
}
Ejemplo n.º 2
0
static long
ipwrite(Chan *ch, void *a, long n, vlong off)
{
	Conv *c;
	Proto *x;
	char *p;
	Cmdbuf *cb;
	Fs *f;

	f = ipfs[ch->dev];

	switch(TYPE(ch->qid)) {
	default:
		error(Eperm);
	case Qdata:
		x = f->p[PROTO(ch->qid)];
		c = x->conv[CONV(ch->qid)];
		if(c->sfd < 0)
			error(Ehungup);
		qlock(&c->wlock);
		if(waserror()){
			qunlock(&c->wlock);
			nexterror();
		}
		if(c->headers) {
			if(n < c->headers)
				error(Eshort);
			p = a;
			n = so_send(c->sfd, p + c->headers, n - c->headers, p, c->headers);
			if(n >= 0)
				n += c->headers;
		} else
			n = so_send(c->sfd, a, n, nil, 0);
		poperror();
		qunlock(&c->wlock);
		if(n < 0)
			oserror();
		break;
	case Qarp:
		return arpwrite(a, n);
	case Qndb:
		if(off > strlen(f->ndb))
			error(Eio);
		if(off+n >= sizeof(f->ndb)-1)
			error(Eio);
		memmove(f->ndb+off, a, n);
		f->ndb[off+n] = 0;
		f->ndbvers++;
		f->ndbmtime = seconds();
		break;
	case Qctl:
		x = f->p[PROTO(ch->qid)];
		c = x->conv[CONV(ch->qid)];
		cb = parsecmd(a, n);
		qlock(&c->l);
		if(waserror()){
			qunlock(&c->l);
			free(cb);
			nexterror();
		}
		if(cb->nf < 1)
			error("short control request");
		if(strcmp(cb->f[0], "connect") == 0)
			connectctlmsg(x, c, cb);
		else if(strcmp(cb->f[0], "announce") == 0)
			announcectlmsg(x, c, cb);
		else if(strcmp(cb->f[0], "bind") == 0)
			bindctlmsg(x, c, cb);
		else if(strcmp(cb->f[0], "ttl") == 0){
			/* ignored */
		} else if(strcmp(cb->f[0], "tos") == 0){
			/* ignored */
		} else if(strcmp(cb->f[0], "ignoreadvice") == 0){
			/* ignored */
		} else if(strcmp(cb->f[0], "headers4") == 0){
			if(c->p->stype != S_UDP)
				error(Enoctl);
			c->headers = OUdphdrlenv4;
		} else if(strcmp(cb->f[0], "oldheaders") == 0){
			if(c->p->stype != S_UDP)
				error(Enoctl);
			c->headers = OUdphdrlen;
		} else if(strcmp(cb->f[0], "headers") == 0){
			if(c->p->stype != S_UDP)
				error(Enoctl);
			c->headers = Udphdrlen;
		} else if(strcmp(cb->f[0], "hangup") == 0){
			if(c->p->stype != S_TCP)
				error(Enoctl);
			qunlock(&c->l);
			if(waserror()){
				qlock(&c->l);
				nexterror();
			}
			/* TO DO: check fd status if socket close/hangup interrupted */
			if(c->sfd >= 0 && so_hangup(c->sfd, 1) < 0)
				oserror();
			qlock(&c->l);
			poperror();
			c->sfd = -1;
			c->state = Hungup;
		} else if(strcmp(cb->f[0], "keepalive") == 0){
			if(c->p->stype != S_TCP)
				error(Enoctl);
			if(c->sfd < 0)
				error("not connected");
			so_keepalive(c->sfd, cb->nf>1? atoi(cb->f[1]): 0);
		} else
			error(Enoctl);
		poperror();
		qunlock(&c->l);
		free(cb);
		break;
	}
	return n;
}
Ejemplo n.º 3
0
int cg_socket_write(CgSocket *sock, char *cmd, int cmdLen)
{
	int nSent;
	int nTotalSent = 0;
	int cmdPos = 0;
	int retryCnt = 0;

	cg_log_debug_l4("Entering...\n");

	if (cmdLen <= 0)
		return 0;

	do {
#if defined(CG_USE_OPENSSL)
		if (cg_socket_isssl(sock) == FALSE) {
#endif

#if defined(BTRON) || (defined(TENGINE) && !defined(CG_TENGINE_NET_KASAGO))
		nSent = so_send(sock->id, (B*)(cmd + cmdPos), cmdLen, 0);
#elif defined(TENGINE) && defined(CG_TENGINE_NET_KASAGO)
		nSent = ka_send(sock->id, (B*)(cmd + cmdPos), cmdLen, 0);
#elif defined(ITRON)
		nSent = tcp_snd_dat(sock->id, cmd + cmdPos, cmdLen, TMO_FEVR);
#else
		nSent = send(sock->id, cmd + cmdPos, cmdLen, 0);
#endif

#if defined(CG_USE_OPENSSL)
		}
		else {
			nSent = SSL_write(sock->ssl, cmd + cmdPos, cmdLen);
		}
#endif

		/* Try to re-send in case sending has failed */
		if (nSent <= 0)
		{
			retryCnt++;
			if (CG_NET_SOCKET_SEND_RETRY_CNT < retryCnt)
			{
				/* Must reset this because otherwise return
				   value is interpreted as something else than
				   fault and this function loops forever */
				nTotalSent = 0;
				break;
			}

			cg_wait(CG_NET_SOCKET_SEND_RETRY_WAIT_MSEC);
		}
		else
		{
			nTotalSent += nSent;
			cmdPos += nSent;
			cmdLen -= nSent;
			retryCnt = 0;
		}

	} while (0 < cmdLen);

#ifdef SOCKET_DEBUG
cg_log_debug_s("w %d : %s\n", nTotalSent, ((cmd != NULL) ? cmd : ""));
#endif
	
	cg_log_debug_l4("Leaving...\n");

	return nTotalSent;
}
Ejemplo n.º 4
0
long
ipwrite(Chan *ch, void *a, long n, vlong offset)
{
	Conv *c;
	Proto *x;
	int r, nf;
	char *p, *fields[3], buf[128];

	switch(TYPE(ch->qid)) {
	default:
		error(Eperm);
	case Qcs:
		return cswrite(ch, a, n, offset);
	case Qctl:
		x = &proto[PROTO(ch->qid)];
		c = x->conv[CONV(ch->qid)];
		if(n > sizeof(buf)-1)
			n = sizeof(buf)-1;
		memmove(buf, a, n);
		buf[n] = '\0';

		nf = tokenize(buf, fields, 3);
		if(strcmp(fields[0], "connect") == 0){
			switch(nf) {
			default:
				error("bad args to connect");
			case 2:
				p = setraddrport(c, fields[1]);
				if(p != 0)
					error(p);
				break;
			case 3:
				p = setraddrport(c, fields[1]);
				if(p != 0)
					error(p);
				c->lport = atoi(fields[2]);
				setlport(c);
				break;
			}
			so_connect(c->sfd, c->raddr, c->rport);
			setladdr(c);
			c->state = "Established";
			return n;
		}
		if(strcmp(fields[0], "announce") == 0) {
			switch(nf){
			default:
				error("bad args to announce");
			case 2:
				setladdrport(c, fields[1]);
				break;
			}
			so_listen(c->sfd);
			c->state = "Announced";
			return n;
		}
		if(strcmp(fields[0], "bind") == 0){
			switch(nf){
			default:
				error("bad args to bind");
			case 2:
				c->lport = atoi(fields[1]);
				break;
			}
			setlport(c);
			return n;
		}
		error("bad control message");
	case Qdata:
		x = &proto[PROTO(ch->qid)];
		c = x->conv[CONV(ch->qid)];
		r = so_send(c->sfd, a, n, 0);
		if(r < 0){
			oserrstr();
			nexterror();
		}
		return r;
	}
	return n;
}