static coroutine void connector(void) {
    tcpsock s = tcpconnect(iplocal("127.0.0.1", 5555, 0), -1);
    assert(s);
    char buf[1];
    tcprecv(s, buf, 1, -1);
    assert(0);
}
Beispiel #2
0
coroutine void client(int port) {
    ipaddr addr = ipremote("127.0.0.1", port, 0, -1);
    tcpsock cs = tcpconnect(addr, -1);
    assert(cs);

    char ipstr[16] = {0};
    ipaddrstr(addr, ipstr);
    assert(errno == 0);
    assert(strcmp(ipstr, "127.0.0.1") == 0);

    int fd = tcpdetach(cs);
    assert(fd != -1);
    cs = tcpattach(fd, 0);
    assert(cs);

    msleep(now() + 100);

    char buf[16];
    size_t sz = tcprecv(cs, buf, 3, -1);
    assert(sz == 3 && buf[0] == 'A' && buf[1] == 'B' && buf[2] == 'C');

    sz = tcpsend(cs, "123\n45\n6789", 11, -1);
    assert(sz == 11 && errno == 0);
    tcpflush(cs, -1);
    assert(errno == 0);

    tcpclose(cs);
}
Beispiel #3
0
size_t net_peer_recv(net_peer_t* peer, void* buf, size_t len, int64_t deadline) {
	switch(peer->type) {
		case NET_PROTO_UNIX:
			return unixrecv((unixsock)peer->socket, buf, len, deadline);
		case NET_PROTO_TCP:
			return tcprecv((tcpsock)peer->socket, buf, len, deadline);
		case NET_PROTO_UDP:
			return udprecv((udpsock)peer->socket, 0, buf, len, deadline);
	}

	return 0;
}
Beispiel #4
0
void client(void) {
    tcpsock cs = tcpconnect("127.0.0.1:5555");
    assert(cs);

    char buf[16];
    ssize_t sz = tcprecv(cs, buf, 3);
    assert(buf[0] == 'A' && buf[1] == 'B' && buf[2] == 'C');

    tcpsend(cs, "123\n45\n6789", 11);
    int rc = tcpflush(cs);
    assert(rc == 0);

    tcpclose(cs);
}
int main(int argc, char *argv[]) {
    if(argc != 3) {
        printf("usage: c10k <parallel-connections> <roundtrip-count>\n");
        return 1;
    }
    long conns = atol(argv[1]);
    long roundtrips = atol(argv[2]);
    assert(conns >= 1);

    tcpsock ls = tcplisten(iplocal("127.0.0.1", 5555, 0), 10);
    assert(ls);
    int i;
    for(i = 0; i != conns - 1; ++i) {
        go(connector());
        tcpsock as = tcpaccept(ls, -1);
        assert(as);
    }
    go(sender(roundtrips));
    tcpsock as = tcpaccept(ls, -1);
    assert(as);

    int64_t start = now();

    char buf[1];
    size_t nbytes;
    for(i = 0; i != roundtrips; ++i) {
        nbytes = tcpsend(as, "A", 1, -1);
        assert(errno == 0);
        assert(nbytes == 1);
        tcpflush(as, -1);
        assert(errno == 0);
        nbytes = tcprecv(as, buf, 1, -1);
        assert(errno == 0);
        assert(nbytes == 1);
        assert(buf[0] == 'A');
    }

    int64_t stop = now();
    long duration = (long)(stop - start);
    long us = (duration * 1000) / roundtrips;

    printf("done %ld roundtrips in %f seconds\n",
        roundtrips, ((float)duration) / 1000);
    printf("duration of a single roundtrip: %ld us\n", us);
    printf("roundtrips per second: %ld\n",
        (long)(roundtrips * 1000 / duration));

    return 0;
}
Beispiel #6
0
int main(void) {
    go(daemon());
    msleep(now() + 500);
    tcpmuxsock ls = tcpmuxlisten(5557, "foo", -1);
    assert(ls);
    go(doconnect());
    tcpsock s = tcpmuxaccept(ls, -1);
    assert(s);
    char buf[3];
    tcprecv(s, buf, sizeof(buf), -1);
    assert(errno == 0);
    assert(buf[0] == 'a' && buf[1] == 'b' && buf[2] == 'c');
    tcpclose(s);
    tcpmuxclose(ls);

    return 0;
}
static coroutine void sender(long roundtrips) {
    tcpsock s = tcpconnect(iplocal("127.0.0.1", 5555, 0), -1);
    assert(s);
    char buf[1];
    int i;
    size_t nbytes;
    for(i = 0; i != roundtrips; ++i) {
        nbytes = tcprecv(s, buf, 1, -1);
        assert(errno == 0);
        assert(nbytes == 1);
        assert(buf[0] == 'A');
        nbytes = tcpsend(s, "A", 1, -1);
        assert(errno == 0);
        assert(nbytes == 1);
        tcpflush(s, -1);
        assert(errno == 0);
    }
}
Beispiel #8
0
int main() {
    char buf[16];

    tcpsock ls = tcplisten(iplocal(NULL, 5555, 0), 10);
    assert(ls);

    int fd = tcpdetach(ls);
    assert(fd != -1);
    ls = tcpattach(fd, 1);
    assert(ls);
    assert(tcpport(ls) == 5555);

    go(client(5555));

    tcpsock as = tcpaccept(ls, -1);

    /* Test deadline. */
    int64_t deadline = now() + 30;
    size_t sz = tcprecv(as, buf, sizeof(buf), deadline);
    assert(sz == 0 && errno == ETIMEDOUT);
    int64_t diff = now() - deadline;
    assert(diff > -20 && diff < 20); 

    sz = tcpsend(as, "ABC", 3, -1);
    assert(sz == 3 && errno == 0);
    tcpflush(as, -1);
    assert(errno == 0);

    sz = tcprecvuntil(as, buf, sizeof(buf), "\n", 1, -1);
    assert(sz == 4);
    assert(buf[0] == '1' && buf[1] == '2' && buf[2] == '3' && buf[3] == '\n');
    sz = tcprecvuntil(as, buf, sizeof(buf), "\n", 1, -1);
    assert(sz == 3);
    assert(buf[0] == '4' && buf[1] == '5' && buf[2] == '\n');
    sz = tcprecvuntil(as, buf, 3, "\n", 1, -1);
    assert(sz == 3);
    assert(buf[0] == '6' && buf[1] == '7' && buf[2] == '8');

    tcpclose(as);
    tcpclose(ls);

    return 0;
}
Beispiel #9
0
size_t tcprecvuntil(tcpsock s, void *buf, size_t len,
      const char *delims, size_t delimcount, int64_t deadline) {
    if(s->type != MILL_TCPCONN)
        mill_panic("trying to receive from an unconnected socket");
    char *pos = (char*)buf;
    size_t i;
    for(i = 0; i != len; ++i, ++pos) {
        size_t res = tcprecv(s, pos, 1, deadline);
        if(res == 1) {
            size_t j;
            for(j = 0; j != delimcount; ++j)
                if(*pos == delims[j])
                    return i + 1;
        }
        if (errno != 0)
            return i + res;
    }
    errno = ENOBUFS;
    return len;
}
Beispiel #10
0
/* Gets one CRLF-delimited line from the socket. Trims all leading and trailing
   whitesepace. Replaces any remaining whitespace sequences by single space. */
static int wsock_getline(wsock s, char *buf, size_t len, int64_t deadline) {
    size_t sz = tcprecvuntil(s->u, buf, len, "\r", 1, deadline);
    if(errno != 0)
        return -1;
    sz--;
    char c;
    tcprecv(s->u, &c, 1, deadline);
    if(errno != 0)
        return -1;
    if(c != '\n') {
        errno = EPROTO;
        return -1;
    }
    size_t i;
    for(i = 0; i != sz; ++i) {
        if(buf[i] < 32 || buf[i] > 127) {
            errno = EPROTO;
            return -1;
        }
    }
    i = 0;
    while(i != sz && isspace(buf[i]))
        ++i;
    size_t pos = 0;
    while(i != sz) {
        if(isspace(buf[i])) {
            while(i != sz && isspace(buf[i]))
                ++i;
            --i;
        }
        buf[pos++] = buf[i++];
    }
    if(pos && isspace(buf[pos - 1]))
        --pos;
    return pos;
}
Beispiel #11
0
PROCESS_THREAD(mqtt_socket_process, ev, data)
{
	PROCESS_BEGIN();
	
    SOCKETMSG msg;
	static struct etimer mqtt_socket_timer;
	int recv;


	mqtt_tcp_socket_init();
	app_mqtt_init(&g_stMQTTBroker);
	mqtt_tcp_connect(MQTT_SERVER_ADDR, MQTT_SERVER_PORT);

	while(1) 
	{
		PROCESS_WAIT_EVENT();

		if(ev == resolv_event_found)
		{
			char *p_hostname = (char *)data;

			if(strcmp(p_hostname, MQTT_SERVER_ADDR))
				continue;
			
			uip_ipaddr_t addr;
			uip_ipaddr_t *p_addr = &addr;
			uip_ip4addr_t remote_ip_addr;
			resolv_lookup(p_hostname, &p_addr);
			uip_ipaddr_copy(&remote_ip_addr, p_addr);

			char ip_str[20]= {0}; 
			sprintf(ip_str,"%d.%d.%d.%d", remote_ip_addr.u8[0], remote_ip_addr.u8[1], remote_ip_addr.u8[2], remote_ip_addr.u8[3]);
		
			mqtt_tcp_connect(ip_str, MQTT_SERVER_PORT);	
		}
		else if(ev == PROCESS_EVENT_EXIT)
		{
			mqtt_disconnect(&g_stMQTTBroker);
			tcpclose(g_mqtt_socket_para.fd);
			break;
		}
		else if(ev == PROCESS_EVENT_MSG)
		{
            msg = *(SOCKETMSG *)data;

			if(msg.status == SOCKET_CONNECTED) 
			{
				printf("MQTT tcp socket(%d) connected\n", msg.socket);
				g_mqtt_socket_para.connect_status = SOCKET_CONNECTED;
				tcp_set_send_buffer_size(g_mqtt_socket_para.fd, MQTT_SOCKET_SEND_BUF_SIZE);

				mqtt_login_server(&g_stMQTTBroker);
			}
			else if(msg.status == SOCKET_CLOSED)
			{
				if(g_mqtt_socket_para.connect_status == SOCKET_CREATE)
					printf("Socked(%d) create fail and retry...\n", msg.socket);
				else
					printf("MQTT tcp socket(%d) closed\n", msg.socket);		

				g_mqtt_socket_para.fd = -1;
				g_mqtt_socket_para.connect_status = SOCKET_CLOSED;
				etimer_set(&mqtt_socket_timer, 3*CLOCK_SECOND);
				PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&mqtt_socket_timer));
				
				mqtt_tcp_connect(MQTT_SERVER_ADDR, MQTT_SERVER_PORT);				
			}
			else if(msg.status == SOCKET_SENDACK)
			{
			
			}
			else if(msg.status == SOCKET_NEWDATA)
			{
				g_mqtt_socket_para.connect_status = SOCKET_NEWDATA;

				recv = tcprecv(g_mqtt_socket_para.fd, g_mqtt_socket_para.recv_buf, MQTT_SOCKET_RECV_BUF_SIZE);
				if(recv<=0)
				{
					printf("tcprecv error! ret:%d\n", recv);
					continue;
				}
				
				app_parse_mqttmsg(g_mqtt_socket_para.recv_buf);	
			}
		
		}
		

	}
	
	PROCESS_END();
}
Beispiel #12
0
size_t wsockrecv(wsock s, void *msg, size_t len, int64_t deadline) {
    if(s->flags & WSOCK_LISTENING) {errno = EOPNOTSUPP; return 0;}
    if(s->flags & WSOCK_BROKEN) {errno = ECONNABORTED; return 0;}
    size_t res = 0;
    while(1) {
        uint8_t hdr1[2];
        tcprecv(s->u, hdr1, 2, deadline);
        if(errno != 0) {s->flags |= WSOCK_BROKEN; return 0;}
        if(hdr1[0] & 0x70) {
            s->flags &= WSOCK_BROKEN; errno = EPROTO; return 0;}
        int opcode = hdr1[0] & 0x0f;
        if(opcode == 8) {
            if(!(s->flags & WSOCK_DONE)) {
                /* TODO: Close frames from client should be masked. */
                tcpsend(s->u, "\x88\x00", 2, deadline);
                tcpflush(s->u, deadline);
                s->flags |= (WSOCK_BROKEN & WSOCK_DONE);
            }
            errno = ECONNRESET;
            return 0;
        }
        if(opcode == 9) {
            /* TODO: Account for pings and pongs with payload. */
            if(!(s->flags & WSOCK_DONE)) {
                tcpsend(s->u, "\x8A\x00", 2, deadline);
                if(errno != 0) {s->flags &= WSOCK_BROKEN; return 0;}
                tcpflush(s->u, deadline);
                if(errno != 0) {s->flags &= WSOCK_BROKEN; return 0;}
            }
            continue;
        }
        if(opcode == 10) {
            /* TODO: Account for pings and pongs with payload. */
            /* TODO: Do we want to make exiting the function here optional? */
            errno = EAGAIN;
            return 0;
        }
        if(!!(s->flags & WSOCK_CLIENT) ^ !(hdr1[1] & 0x80)) {
            s->flags &= WSOCK_BROKEN; errno = EPROTO; return 0;}
        size_t sz = hdr1[1] & 0x7f;
        if(sz == 126) {
            uint8_t hdr2[2];
            tcprecv(s->u, hdr2, 2, deadline);
            if(errno != 0) {s->flags |= WSOCK_BROKEN; return 0;}
            sz = wsock_gets(hdr2);
        }
        else if(sz == 127) {
            uint8_t hdr2[8];
            tcprecv(s->u, hdr2, 8, deadline);
            if(errno != 0) {s->flags |= WSOCK_BROKEN; return 0;}
            sz = wsock_getll(hdr2);
        }
        uint8_t mask[4];
        if(!(s->flags & WSOCK_CLIENT)) {
            tcprecv(s->u, mask, 4, deadline);
            if(errno != 0) {s->flags |= WSOCK_BROKEN; return 0;}
        }
        size_t toread = sz < len ? sz : len;
        if(toread > 0) {
            tcprecv(s->u, msg, toread, deadline);
            if(errno != 0) {s->flags |= WSOCK_BROKEN; return 0;}
        }
        if(!(s->flags & WSOCK_CLIENT)) {
            size_t i;
            for(i = 0; i != toread; ++i)
                ((uint8_t*)msg)[i] ^= mask[i % 4];
        }
        if(sz > toread) {
            tcprecv(s->u, NULL, sz - toread, deadline);
            if(errno != 0) {s->flags |= WSOCK_BROKEN; return 0;}
        }
        res += sz;
        if(hdr1[0] & 0x80)
            break;
        msg = ((uint8_t*)msg) + sz;
        len -= sz;
    }
    return res;
}
Beispiel #13
0
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(http_req_process, ev, data)
{
    static struct etimer httptimeout;
	SOCKETMSG msg;

    PROCESS_BEGIN();

    while(1)
    {
		//wait for TCP connected or uip_timeout.
		PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_MSG || ev == PROCESS_EVENT_TIMER || ev == PROCESS_EVENT_EXIT);
        if(ev == PROCESS_EVENT_MSG)
        {
    		msg = *(SOCKETMSG *)data;
    		if(msg.status == SOCKET_CONNECTED)
    		{
    		    //send out the http request.
    		    if(httpreqdata.cmdlen)
                    tcpsend(httpreqdata.httpsock, httpreqdata.httpcmd, httpreqdata.cmdlen);
    		}
    		else if(msg.status == SOCKET_SENDACK)
    		{
    		    //set timeot for http response.
    		    etimer_set(&httptimeout, 10 * CLOCK_CONF_SECOND);
    		}
    		else if(msg.status == SOCKET_NEWDATA)
    		{
    			//Get http response, parse response and close socket.
    			etimer_stop(&httptimeout);
                httpreqdata.rsplen = tcprecv(httpreqdata.httpsock, httpreqdata.httprsp, HTTPRSP_MAX);
                tcpclose(httpreqdata.httpsock);
                httpreqdata.httpsock = -1;
                httpreqdata.httpstatus = HTTP_IDLE;
                if(httpreqdata.rsplen > 0 && httpreqdata.callbackfn)
                {
                    httpreqdata.httprsp[httpreqdata.rsplen] = 0;
                    httprsp_parse(httpreqdata.httprsp, httpreqdata.rsplen);
                }
    		}
    		else if(msg.status == SOCKET_CLOSED)
    		{
    			//socket closed, if it is unnormal case, notify upper layer.
    			if(httpreqdata.httpstatus != HTTP_IDLE)
                {
                    if(httpreqdata.callbackfn)
                    {
                        httpmsg.msgtype = HTTPREQ_CONN_ERROR;
                        httpmsg.rsp = NULL;
                        httpreqdata.callbackfn(&httpmsg);
                    }
                    httpreqdata.httpsock = -1;
                    httpreqdata.httpstatus = HTTP_IDLE;
                }
    		}
        }
        else if(ev == PROCESS_EVENT_TIMER)
        {
            //http response timeout, close socket and notify upper layer.
            tcpclose(httpreqdata.httpsock);
            httpreqdata.httpsock = -1;
            httpreqdata.httpstatus = HTTP_IDLE;
            if(httpreqdata.callbackfn)
            {
                httpmsg.msgtype = HTTPREQ_RSP_TIMEOUT;
                httpmsg.rsp = NULL;
                httpreqdata.callbackfn(&httpmsg);
            }
        }
        else if(ev == PROCESS_EVENT_EXIT)
        {
            break;
        }
    }

    PROCESS_END();
}