예제 #1
0
파일: libtcpip.cpp 프로젝트: gozfree/src
int udp_server_start(u_short server_port)
{
	int i = 0;
	int ret;
	char* recv_buf;
	SOCKET sock;
	recv_buf = (char*)malloc(512);
	if(recv_buf == NULL)
	{
		fprintf(stdout, "malloc failed!\n");
		return -1;
	}
	memset(recv_buf, 0, 512);
	socket_init();
	udp_socket(&sock);
	udp_bind(&sock, server_port);
	while(1)
	{
		ret = udp_recvfrom(&sock, recv_buf, LOCAL_HOST, 5061);
		if(ret == 0)
		{
			printf("udp client connect times = %d\n", i);
			printf("udp receive buffer: %s\n", (char*)recv_buf);
			memset(recv_buf, 0, 512);
			i++;
		}
	}
	return 0;
}
예제 #2
0
파일: test_udp.c 프로젝트: frese/mbuni
Usage: test_udp client server_port\n\
       test_udp server server_port\n\
";

#define PING "ping"
#define PONG "pong"
#define TIMES 10

static void client(int port) {
    int i, s;
    Octstr *ping, *pong, *addr, *from;

    s = udp_client_socket();
    ping = octstr_create(PING);
    addr = udp_create_address(octstr_create("localhost"), port);
    if (s == -1 || addr == NULL)
        panic(0, "Couldn't set up client socket.");

    for (i = 0; i < TIMES; ++i) {
        if (udp_sendto(s, ping, addr) == -1)
            panic(0, "Couldn't send ping.");
        if (udp_recvfrom(s, &pong, &from) == -1)
            panic(0, "Couldn't receive pong");
        info(0, "Got <%s> from <%s:%d>", octstr_get_cstr(pong),
             octstr_get_cstr(udp_get_ip(from)),
             udp_get_port(from));
    }
}
예제 #3
0
/**
 * Copies the received data from the socket in its data buffer
 */
static void read_socket (DS_Socket* ptr)
{
    if (!ptr)
        return;

    /* Initialize temporary buffer */
    int read = -1;
    sds data = sdsnewlen (NULL, 1024);

    /* Read TCP socket */
    if (ptr->type == DS_SOCKET_TCP)
        read = recv (ptr->info.sock_in, data, sdslen (data), 0);

    /* Read UDP socket */
    if (ptr->type == DS_SOCKET_UDP)
        read = udp_recvfrom (ptr->info.sock_in,
                             data, sdslen (data),
                             ptr->address, ptr->info.in_service, 0);

    /* We received some data, copy it to socket's buffer */
    if (read > 0) {
        DS_FREESTR (ptr->info.buffer);
        ptr->info.buffer = sdsnewlen (NULL, read);

        int i;
        for (i = 0; i < read; ++i)
            ptr->info.buffer [i] = data [i];
    }

    /* De-allocate temporary data */
    DS_FREESTR (data);
}
예제 #4
0
파일: syscall.c 프로젝트: rasco/armnet
int syscall_handler(int num, struct syscall_arguments *args)
{
    interrupt_unmask();
    
    switch (num)
    {
        case ADDPROCESS:
            interrupt_mask();
                process_add((void (*)())args->arg1);
            interrupt_unmask();
        break;
        case YIELD:
            interrupt_sleepinsyscall();
        break;
        
        case UDPSEND:
            return udp_output(args->arg1, (struct sockaddr*)args->arg2, 
                (char *)args->arg3, args->arg4);
        break;
        case UDPRECV:
            return udp_recvfrom(args->arg1, (struct sockaddr*)args->arg2, 
                (char *)args->arg3, args->arg4);
        break;
        case UDPSOCKET: 
            return udp_socket();
        break;
        case UDPBIND:
            return udp_bind(args->arg1, (struct sockaddr*)args->arg2);
        break;
        case UDPCLOSE:
            return udp_close(args->arg1);
        break;
        
        case TCPCONNECT:
            return tcp_connect(args->arg1, (struct sockaddr*)args->arg2);
        break;
        
        case TCPSEND:
            return tcp_send(args->arg1, (char *)args->arg2, args->arg3);
        break;
        case TCPRECV:
            return tcp_recv(args->arg1, (char *)args->arg2, args->arg3);
        break;
        case TCPSOCKET: 
            return tcp_socket();
        break;
        case TCPBIND:
            return tcp_bind(args->arg1, (struct sockaddr*)args->arg2);
        break;
        case TCPCLOSE:
            return tcp_close(args->arg1);
        break;
        case TCPLISTEN:
            return tcp_listen(args->arg1);
        break;
    }
    
    return 0;
}
예제 #5
0
ssize_t usys_recvfrom(int *err, uuprocess_t *u, int fd, void *buf, size_t buflen, int flags,
                      struct sockaddr *from, socklen_t *fromlen)
{
    if( u == 0 )
    {
        *err = ENOTSOCK; // TODO correct?
        return -1;
    }

    CHECK_FD(fd);
    struct uufile *f = GETF(fd);

    struct uusocket *us = f->impl;

    if( *fromlen < (int)sizeof(struct sockaddr_in) )
    {
        *err = EINVAL;
        return -1;
    }

    if( ! (f->flags & UU_FILE_FLAG_NET))
    {
        *err = ENOTSOCK;
        return -1;
    }

    if( flags )
        SHOW_ERROR( 0, "I don't know this flag %d", flags );

    i4sockaddr tmp_addr;
    //struct sockaddr_in *sfrom = (struct sockaddr_in *)from;

    // FIXME TODO ERR allways times out in 5 sec
    int len = udp_recvfrom( us->prot_data, buf, buflen, &tmp_addr, SOCK_FLAG_TIMEOUT, 5000000L );
    if( len < 0 )
    {
        SHOW_ERROR( 7, "ret = %d", len );
        *err = -len;
        goto ret;
    }

    SHOW_FLOW( 8, "flags %x", flags );
    /*
    SHOW_FLOW( 7, "port %d, ip %s", tmp_addr.port, inet_itoa(htonl(NETADDR_TO_IPV4(tmp_addr.addr))) );

    sfrom->sin_port = htons(tmp_addr.port);
    sfrom->sin_addr.s_addr = htonl(NETADDR_TO_IPV4(tmp_addr.addr));
    sfrom->sin_family = PF_INET;
    sfrom->sin_len = sizeof(struct sockaddr_in);

    *fromlen = sfrom->sin_len;
    */
    errno_t rc = sockaddr_int2unix( from, fromlen, &tmp_addr );
    if( rc )
        *fromlen = 0;

ret:
    return *err ? -1 : len;
}
예제 #6
0
파일: main.c 프로젝트: dgoulet/debind
/*
 * Wait on socket using recvfrom(2) for a UDP DNS request.
 */
static ssize_t dns_udp_recv_query(int sock, char *buf, size_t buf_size,
		struct sockaddr *src_addr)
{
	/*
	 * We clear the two first bytes in order to use that same buffer for the
	 * TCP request that needs the first two bytes used for the length of the
	 * DNS query.
	 */
	return udp_recvfrom(sock, buf + 2, buf_size, src_addr);
}
예제 #7
0
파일: bootp.c 프로젝트: animotron/animos
static errno_t
bootprecv( struct bootp_state *bstate, void *udp_sock, struct bootp *bp, size_t len, size_t *retlen )
{
    SHOW_FLOW0( 3, "bootp_recv");

    sockaddr dest_addr;
    dest_addr.port = IPPORT_BOOTPS; // dest port

    dest_addr.addr.len = 4;
    dest_addr.addr.type = ADDR_TYPE_IP;
    // INADDR_BROADCAST
    //NETADDR_TO_IPV4(dest_addr.addr) = IPV4_DOTADDR_TO_ADDR(0xFF, 0xFF, 0xFF, 0xFF);
    NETADDR_TO_IPV4(dest_addr.addr) = IPV4_DOTADDR_TO_ADDR(0, 0, 0, 0);

    int n = udp_recvfrom(udp_sock, bp, len, &dest_addr, SOCK_FLAG_TIMEOUT, 2000000l);

    if( 0 >= n )
    {
        SHOW_ERROR( 0, "UDP recv err = %d", n);
        return ETIMEDOUT; // TODO errno
    }

    if (n == -1 || n < (int)(sizeof(struct bootp) - BOOTP_VENDSIZE))
        goto bad;

    SHOW_FLOW( 3, "bootprecv: recv %d bytes", n);

    if (bp->bp_xid != htonl(xid)) {
        SHOW_ERROR( 1, "bootprecv: expected xid 0x%x, got 0x%x",
                   xid, ntohl(bp->bp_xid));
        goto bad;
    }

    SHOW_FLOW0( 3, "bootprecv: got one!");

    /* Suck out vendor info */
    if (bcmp(vm_rfc1048, bp->bp_vend, sizeof(vm_rfc1048)) == 0) {
        if(vend_rfc1048(bstate, bp->bp_vend, sizeof(bp->bp_vend)) != 0)
            goto bad;
    }
#ifdef BOOTP_VEND_CMU
    else if (bcmp(vm_cmu, bp->bp_vend, sizeof(vm_cmu)) == 0)
        vend_cmu(bstate,bp->bp_vend);
#endif
    else
        SHOW_ERROR( 0, "bootprecv: unknown vendor 0x%lx", (long)bp->bp_vend);

    if(retlen) *retlen = n;

    return 0;
bad:
    //errno = 0;
    return EINVAL;
}
예제 #8
0
파일: socket.c 프로젝트: barryzxy/RIOT
int32_t socket_base_recvfrom(int s, void *buf, uint32_t len, int flags,
                                sockaddr6_t *from, uint32_t *fromlen)
{
    if (udp_socket_compliancy(s)) {
        return udp_recvfrom(s, buf, len, flags, from, fromlen);
    }
    else if (tcp_socket_compliancy(s)) {
        return tcp_recv(s, buf, len, flags);
    }

    printf("Socket Type not supported!\n");
    return -1;
}
예제 #9
0
int main(void)
{
    int server_fd;
    char buf[128];
    struct sockaddr client;
    socklen_t client_len = sizeof(struct sockaddr);

    server_fd = udp_server("127.0.0.1", "21114");
    udp_recvfrom(server_fd, buf, sizeof(buf), &client, &client_len);
    strcat(buf, " from server");
    udp_sendto(server_fd, buf, sizeof(buf), &client, client_len);
    udp_close(server_fd);
}
예제 #10
0
파일: test_udp.c 프로젝트: frese/mbuni
static void server(int port) {
    int i, s;
    Octstr *ping, *pong, *from;

    s = udp_bind(port,"0.0.0.0");
    pong = octstr_create(PONG);
    if (s == -1)
        panic(0, "Couldn't set up client socket.");

    for (i = 0; i < TIMES; ++i) {
        if (udp_recvfrom(s, &ping, &from) == -1)
            panic(0, "Couldn't receive ping");
        info(0, "Got <%s> from <%s:%d>", octstr_get_cstr(ping),
             octstr_get_cstr(udp_get_ip(from)),
             udp_get_port(from));
        if (udp_sendto(s, pong, from) == -1)
            panic(0, "Couldn't send pong.");
    }
}
예제 #11
0
errno_t dns_request(const unsigned char *host, ipv4_addr server, ipv4_addr *result)
{
    // TODO 64 k on stack?
    unsigned char buf[32000];
    //unsigned char buf[65536];
    unsigned char *qname, *reader;

    int i, j, stop;

    struct RES_RECORD answers[20], auth[20], addit[20]; //the replies from the DNS server

    struct DNS_HEADER *dns = NULL;
    struct QUESTION *qinfo = NULL;

#ifdef KERNEL
    void *s;
    int res = udp_open(&s);
    if( res )
    {
        SHOW_ERROR0( 0, "Can't get socket");
        return ENOTSOCK;
    }
#else
    int s = socket(AF_INET , SOCK_DGRAM , IPPROTO_UDP); //UDP packet for DNS queries
#endif
    //SHOW_FLOW0( 2, "got sock");

#ifdef KERNEL
    i4sockaddr addr;
    addr.port = 53;
    addr.addr.len = 4;
    addr.addr.type = ADDR_TYPE_IP;
    NETADDR_TO_IPV4(addr.addr) = server;
#else
    struct sockaddr_in dest;
    dest.sin_family = AF_INET;
    dest.sin_port = htons(53);
    dest.sin_addr.s_addr = inet_addr(dns_servers[0]); //dns servers
#endif

    memset(buf, 0, sizeof(buf));

    //Set the DNS structure to standard queries
    dns = (struct DNS_HEADER *)&buf;

#ifdef KERNEL
    dns->id = (unsigned short) random();
#else
    dns->id = (unsigned short) htons(getpid());
#endif
    dns->qr = 0; //This is a query
    dns->opcode = 0; //This is a standard query
    dns->aa = 0; //Not Authoritative
    dns->tc = 0; //This message is not truncated
    dns->rd = 1; //Recursion Desired
    dns->ra = 0; //Recursion not available! hey we dont have it (lol)
    dns->z = 0;
    dns->ad = 0;
    dns->cd = 0;
    dns->rcode = 0;
    dns->q_count = htons(1); //we have only 1 question
    dns->ans_count = 0;
    dns->auth_count = 0;
    dns->add_count = 0;

    //point to the query portion
    qname =(unsigned char*)&buf[sizeof(struct DNS_HEADER)];
    ChangetoDnsNameFormat(qname , host);
    int qname_len = (strlen((const char*)qname) + 1);

    qinfo =(struct QUESTION*)&buf[sizeof(struct DNS_HEADER) + qname_len]; //fill it

    qinfo->qtype = htons(1); //we are requesting the ipv4 address
    qinfo->qclass = htons(1); //its internet (lol)

    STAT_INC_CNT(STAT_CNT_DNS_REQ);

    SHOW_FLOW0( 3, "Sending Packet");
    int sendLen = sizeof(struct DNS_HEADER) + qname_len + sizeof(struct QUESTION);
#ifdef KERNEL
    int ret = udp_sendto( s, buf, sendLen, &addr);
    if( ret )
#else
    if(sendto(s,(char*)buf, sendLen, 0, (struct sockaddr*)&dest, sizeof(dest)) != sendLen)
#endif
    {
        SHOW_ERROR( 0, "Error sending req, %d", ret);
        goto reterr;
    }
    SHOW_FLOW0( 3, "Sent");

#ifdef KERNEL
    long tmo = 1000L*1000L*2; // 2 sec
    //long tmo = 1000L*10;
    if( udp_recvfrom( s, buf, sizeof(buf),
                     &addr,
                     SOCK_FLAG_TIMEOUT, tmo) <= 0 )
#else
    i = sizeof dest;
    ret = recvfrom (s,(char*)buf,65536,0,(struct sockaddr*)&dest,&i);
    if(ret == 0)
#endif
    {
        SHOW_ERROR0( 1, "Failed");
        goto reterr;
    }
    SHOW_FLOW0( 3, "Received");

    STAT_INC_CNT(STAT_CNT_DNS_ANS);

    dns = (struct DNS_HEADER*) buf;

    //move ahead of the dns header and the query field
    reader = &buf[sizeof(struct DNS_HEADER) + (strlen((const char*)qname)+1) + sizeof(struct QUESTION)];


    if(debug_level_flow > 6)
    {
        printf("The response contains : \n");
        printf("%d Questions.\n",ntohs(dns->q_count));
        printf("%d Answers.\n",ntohs(dns->ans_count));
        printf("%d Authoritative Servers.\n",ntohs(dns->auth_count));
        printf("%d Additional records.\n\n",ntohs(dns->add_count));
    }

    //reading answers
    stop=0;

    for(i=0;i<ntohs(dns->ans_count);i++)
    {
        answers[i].name=ReadName(reader,buf,&stop);
        reader = reader + stop;

        answers[i].resource = (struct R_DATA*)(reader);
        reader = reader + sizeof(struct R_DATA);

        if(ntohs(answers[i].resource->type) == 1) //if its an ipv4 address
        {
            answers[i].rdata = (unsigned char*)malloc(ntohs(answers[i].resource->data_len));

            for(j=0 ; j<ntohs(answers[i].resource->data_len) ; j++)
                answers[i].rdata[j]=reader[j];

            answers[i].rdata[ntohs(answers[i].resource->data_len)] = FIN;

            reader = reader + ntohs(answers[i].resource->data_len);
        }
        else
        {
            answers[i].rdata = ReadName(reader,buf,&stop);
            reader = reader + stop;
        }
    }

    //read authorities
    for(i=0;i<ntohs(dns->auth_count);i++)
    {
        auth[i].name=ReadName(reader,buf,&stop);
        reader+=stop;

        auth[i].resource=(struct R_DATA*)(reader);
        reader+=sizeof(struct R_DATA);

        auth[i].rdata=ReadName(reader,buf,&stop);
        reader+=stop;
    }

    //read additional
    for(i=0;i<ntohs(dns->add_count);i++)
    {
        addit[i].name=ReadName(reader,buf,&stop);
        reader+=stop;

        addit[i].resource=(struct R_DATA*)(reader);
        reader+=sizeof(struct R_DATA);

        if(ntohs(addit[i].resource->type)==1)
        {
            addit[i].rdata = (unsigned char*)malloc(ntohs(addit[i].resource->data_len));
            for(j=0;j<ntohs(addit[i].resource->data_len);j++)
                addit[i].rdata[j]=reader[j];

            addit[i].rdata[ntohs(addit[i].resource->data_len)]= FIN;
            reader+=ntohs(addit[i].resource->data_len);
        }
        else
        {
            addit[i].rdata=ReadName(reader,buf,&stop);
            reader+=stop;
        }
    }

    if(debug_level_flow > 6)
    {

        //print answers
        for(i=0;i<ntohs(dns->ans_count);i++)
        {
            printf("Name : %s ",answers[i].name);

            if(ntohs(answers[i].resource->type)==1) //IPv4 address
            {

                long *p;
                p=(long*)answers[i].rdata;

                struct sockaddr_in a;

                a.sin_addr.s_addr=(*p); //working without ntohl
                printf("has IPv4 address : %s",inet_ntoa(a.sin_addr));
            }
            if(ntohs(answers[i].resource->type)==5) //Canonical name for an alias
                printf("has alias name : %s",answers[i].rdata);

            printf("\n");
        }

        //print authorities
        for(i=0;i<ntohs(dns->auth_count);i++)
        {
            printf("Name : %s ",auth[i].name);
            if(ntohs(auth[i].resource->type)==2)
                printf("has authoritative nameserver : %s",auth[i].rdata);
            printf("\n");
        }

        //print additional resource records
        for(i=0;i<ntohs(dns->add_count);i++)
        {
            printf("Name : %s ",addit[i].name);
            if(ntohs(addit[i].resource->type)==1)
            {
                long *p;
                p=(long*)addit[i].rdata;
                struct sockaddr_in a;
                a.sin_addr.s_addr=(*p); //working without ntohl
                printf("has IPv4 address : %s",inet_ntoa(a.sin_addr));
            }
            printf("\n");
        }

    }

    // return answer
    for( i=0; i < ntohs(dns->ans_count); i++ )
    {
        if( ntohs(answers[i].resource->type) == 1 ) //IPv4 address
        {
            *result = *( (long*)answers[i].rdata);
            udp_close(s);
            return 0;
        }
    }

reterr:
    // No direct answer
    *result = 0;
    udp_close(s);

    return ENOENT;
}
예제 #12
0
void main_task (void *data)
{
	buf_t *p, *r;
	unsigned char addr [4], *output;
	unsigned short port;
#if 1
	mutex_group_t *g;

	debug_printf ("\n\n*** Testing SNMP on UART 1 ***\n\n");

	arp = arp_init (arp_data, sizeof(arp_data), 0);

	/*
	 * Create a group of two locks: timer and eth.
	 */
	g = mutex_group_init (group, sizeof(group));
	mutex_group_add (g, &eth.netif.lock);
	mutex_group_add (g, &timer.decisec);
	ip = mem_alloc (&pool, sizeof (*ip));
	ip_init (ip, &pool, 70, &timer, arp, g);
	arp->ip = ip;

	/*
	 * Create interface eth0 144.206.181.251 / 255.255.255.0
	 */
	/* Reset чипа CS8900A заведен на порт G3.
	 * Он в прямой логике, надо подать туда 0. */
	outb_far (0x08, DDRG);
	clearb_far (3, PORTG);

	/* Добавляем один wait state, т.к. иначе cs8900 не успевает. */
	setb (SRW, MCUCR);
	cs8900_init (&eth, "eth0", 80, &pool, arp);
	route_add_netif (ip, &route, "\220\316\265\373", 24, &eth.netif);

	/*
	 * Add default route to 144.206.181.254
	 */
	route_add_gateway (ip, &default_route, "\0\0\0\0", 0, "\220\316\265\376");
	if (! default_route.netif)
		debug_printf ("test_snmp: no interface for default route!\n");

	snmp_init (&snmp, &pool, ip, snmp_tab, sizeof(snmp_tab),
		SNMP_SERVICE_REPEATER, "Testing SNMP",
		"1.3.6.1.4.1.20520.1.1");

#endif
	udp_socket (&sock, ip, 161);
	debug_printf ("test_snmp: mem available = %u bytes\n",
		mem_available (&pool));

	for (;;) {
		p = udp_recvfrom (&sock, addr, &port);
		debug_printf ("test_snmp: mem available = %u bytes\n",
			mem_available (&pool));

		r = buf_alloc (&pool, 1500, 50);
		if (! r) {
			debug_printf ("test_snmp: out of memory!\n");
			buf_free (p);
			continue;
		}

		output = snmp_execute (&snmp, p->payload, p->len, r->payload,
			r->len, addr);
		buf_free (p);
		if (! output) {
			buf_free (r);
			continue;
		}

		buf_add_header (r, - (output - r->payload));
		udp_sendto (&sock, r, addr, port);
	}
}
예제 #13
0
파일: bb_udp.c 프로젝트: Phonebooth/kannel
static void udp_receiver(void *arg)
{
    Octstr *datagram, *cliaddr;
    int ret;
    Msg *msg;
    Udpc *conn = arg;
    Octstr *ip;

    gwlist_add_producer(incoming_wdp);
    gwlist_add_producer(flow_threads);
    gwthread_wakeup(MAIN_THREAD_ID);
    
    /* remove messages from socket until it is closed */
    while (bb_status != BB_DEAD && bb_status != BB_SHUTDOWN) {

	gwlist_consume(isolated);	/* block here if suspended/isolated */

	if (read_available(conn->fd, 100000) < 1)
	    continue;

	ret = udp_recvfrom(conn->fd, &datagram, &cliaddr);
	if (ret == -1) {
	    if (errno == EAGAIN)
		/* No datagram available, don't block. */
		continue;

	    error(errno, "Failed to receive an UDP");
	    /*
	     * just continue, or is there ANY error that would result
	     * in situation where it would be better to break; or even
	     * die off?     - Kalle 28.2
	     */
	    continue;
	}

	/* discard the message if the client is not allowed */
    	ip = udp_get_ip(cliaddr);
	if (!is_allowed_ip(allow_ip, deny_ip, ip)) {
    	    warning(0, "UDP: Discarding packet from %s, IP is denied.",
		       octstr_get_cstr(ip));
    	    octstr_destroy(datagram);
	} else {
	    debug("bb.udp", 0, "datagram received");
	    msg = msg_create(wdp_datagram);
    
	    msg->wdp_datagram.source_address = udp_get_ip(cliaddr);
	    msg->wdp_datagram.source_port    = udp_get_port(cliaddr);
	    msg->wdp_datagram.destination_address = udp_get_ip(conn->addr);
	    msg->wdp_datagram.destination_port    = udp_get_port(conn->addr);
	    msg->wdp_datagram.user_data = datagram;
    
	    gwlist_produce(incoming_wdp, msg);
	    counter_increase(incoming_wdp_counter);
	}

	octstr_destroy(cliaddr);
	octstr_destroy(ip);
    }    
    gwlist_remove_producer(incoming_wdp);
    gwlist_remove_producer(flow_threads);
}
예제 #14
0
static void proxy_thread(void *arg)
{
    int ss, cs; /* server and client sockets */
    int fl; /* socket flags */
    Octstr *addr = NULL;
    int forward;
    Octstr *tmp;

    run_thread = 1;
    ss = cs = -1;

    /* create client binding, only if we have a remote server
     * and make the client socet non-blocking */
    if (remote_host != NULL) {
        cs = udp_client_socket();
        fl = fcntl(cs, F_GETFL);
        fcntl(cs, F_SETFL, fl | O_NONBLOCK);
        addr = udp_create_address(remote_host, remote_port);
    }

    /* create server binding */
    ss = udp_bind(our_port, octstr_get_cstr(our_host));

    /* make the server socket non-blocking */
    fl = fcntl(ss, F_GETFL);
    fcntl(ss, F_SETFL, fl | O_NONBLOCK);

    if (ss == -1)
        panic(0, "RADIUS: Couldn't set up server socket for port %ld.", our_port);

    while (run_thread) {
        RADIUS_PDU *pdu, *r;
        Octstr *data, *rdata;
        Octstr *from_nas, *from_radius;

        pdu = r = NULL;
        data = rdata = from_nas = from_radius = NULL;
        
        if (read_available(ss, 100000) < 1)
            continue;

        /* get request from NAS */
        if (udp_recvfrom(ss, &data, &from_nas) == -1) {
            if (errno == EAGAIN)
                /* No datagram available, don't block. */
                continue;

            error(0, "RADIUS: Couldn't receive request data from NAS");
            continue;
        }

        tmp = udp_get_ip(from_nas);
        info(0, "RADIUS: Got data from NAS <%s:%d>",
             octstr_get_cstr(tmp), udp_get_port(from_nas));
        octstr_destroy(tmp);
        octstr_dump(data, 0);

        /* unpacking the RADIUS PDU */
        if ((pdu = radius_pdu_unpack(data)) == NULL) {
            warning(0, "RADIUS: Couldn't unpack PDU from NAS, ignoring.");
            goto error;
        }
        info(0, "RADIUS: from NAS: PDU type: %s", pdu->type_name);

        /* authenticate the Accounting-Request packet */
        if (radius_authenticate_pdu(pdu, &data, secret_nas) == 0) {
            warning(0, "RADIUS: Authentication failed for PDU from NAS, ignoring.");
            goto error;
        }

        /* store to hash table if not present yet */
        mutex_lock(radius_mutex);
        forward = update_tables(pdu);
        mutex_unlock(radius_mutex);

        /* create response PDU for NAS */
        r = radius_pdu_create(0x05, pdu);

        /*
         * create response authenticator 
         * code+identifier(req)+length+authenticator(req)+(attributes)+secret 
         */
        r->u.Accounting_Response.identifier = pdu->u.Accounting_Request.identifier;
        r->u.Accounting_Response.authenticator =
            octstr_duplicate(pdu->u.Accounting_Request.authenticator);

        /* pack response for NAS */
        rdata = radius_pdu_pack(r);

        /* creates response autenticator in encoded PDU */
        radius_authenticate_pdu(r, &rdata, secret_nas);

        /* 
         * forward request to remote RADIUS server only if updated
         * and if we have a configured remote RADIUS server 
         */
        if ((remote_host != NULL) && forward) {
            if (udp_sendto(cs, data, addr) == -1) {
                error(0, "RADIUS: Couldn't send to remote RADIUS <%s:%ld>.",
                      octstr_get_cstr(remote_host), remote_port);
            } else 
            if (read_available(cs, remote_timeout) < 1) {
                error(0, "RADIUS: Timeout for response from remote RADIUS <%s:%ld>.",
                      octstr_get_cstr(remote_host), remote_port);
            } else 
            if (udp_recvfrom(cs, &data, &from_radius) == -1) {
                error(0, "RADIUS: Couldn't receive from remote RADIUS <%s:%ld>.",
                      octstr_get_cstr(remote_host), remote_port);
            } else {
                info(0, "RADIUS: Got data from remote RADIUS <%s:%d>.",
                     octstr_get_cstr(udp_get_ip(from_radius)), udp_get_port(from_radius));
                octstr_dump(data, 0);

                /* XXX unpack the response PDU and check if the response
                 * authenticator is valid */
            }
        }

        /* send response to NAS */
        if (udp_sendto(ss, rdata, from_nas) == -1)
            error(0, "RADIUS: Couldn't send response data to NAS <%s:%d>.",
                  octstr_get_cstr(udp_get_ip(from_nas)), udp_get_port(from_nas));

error:
        radius_pdu_destroy(pdu);
        radius_pdu_destroy(r);

        octstr_destroy(rdata);
        octstr_destroy(data);
        octstr_destroy(from_nas);

        debug("radius.proxy", 0, "RADIUS: Mapping table contains %ld elements",
              dict_key_count(radius_table));
        debug("radius.proxy", 0, "RADIUS: Session table contains %ld elements",
              dict_key_count(session_table));
        debug("radius.proxy", 0, "RADIUS: Client table contains %ld elements",
              dict_key_count(client_table));

    }

    octstr_destroy(addr);
}
예제 #15
0
static void udp_receiver(void *arg)
{
    Octstr *datagram, *cliaddr;
    int ret;
    Msg *msg;
    Udpc *conn = arg;
    Octstr *ip;

    gwlist_add_producer(incoming_wdp);
    gwlist_add_producer(flow_threads);
    gwthread_wakeup(MAIN_THREAD_ID);
    
    /* remove messages from socket until it is closed */
    while (1) {

        if (read_available(conn->fd, 100000) < 1)
            continue;

        ret = udp_recvfrom(conn->fd, &datagram, &cliaddr);
        if (ret == -1) {
            if (errno == EAGAIN)
                /* No datagram available, don't block. */
                continue;

            error(errno, "Failed to receive an UDP");
            continue;
        }

    	ip = udp_get_ip(cliaddr);
        msg = msg_create(wdp_datagram);
    
        msg->wdp_datagram.source_address = udp_get_ip(cliaddr);
        msg->wdp_datagram.source_port = udp_get_port(cliaddr);
        msg->wdp_datagram.destination_address = udp_get_ip(conn->addr);
        msg->wdp_datagram.destination_port = udp_get_port(conn->addr);
        msg->wdp_datagram.user_data = datagram;

        info(0, "datagram received <%s:%d> -> <%s:%d>",
             octstr_get_cstr(udp_get_ip(cliaddr)), udp_get_port(cliaddr),
             octstr_get_cstr(udp_get_ip(conn->addr)), udp_get_port(conn->addr));

        dump(msg);

        /* 
         * Descide if this is (a) or (b) UDP packet and add them to the
         * corresponding queues
         */
        if (octstr_compare(conn->addr, conn->map_addr) == 0) {
            gwlist_produce(incoming_wdp, msg);
            counter_increase(incoming_wdp_counter);
        } else {
            gwlist_produce(outgoing_wdp, msg);
	        counter_increase(outgoing_wdp_counter);
        }        

        octstr_destroy(cliaddr);
        octstr_destroy(ip);
    }    
    gwlist_remove_producer(incoming_wdp);
    gwlist_remove_producer(flow_threads);
}
예제 #16
0
ssize_t psock_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
                       int flags,FAR struct sockaddr *from,
                       FAR socklen_t *fromlen)
{
#if defined(CONFIG_NET_UDP) || defined(CONFIG_NET_TCP)
#ifdef CONFIG_NET_IPv6
  FAR struct sockaddr_in6 *infrom = (struct sockaddr_in6 *)from;
#else
  FAR struct sockaddr_in *infrom = (struct sockaddr_in *)from;
#endif
#endif

  ssize_t ret;
  int err;

  /* Verify that non-NULL pointers were passed */

#ifdef CONFIG_DEBUG
  if (!buf)
    {
      err = EINVAL;
      goto errout;
    }
#endif

  /* Verify that the sockfd corresponds to valid, allocated socket */

  if (!psock || psock->s_crefs <= 0)
    {
      err = EBADF;
      goto errout;
    }

  /* If a 'from' address has been provided, verify that it is large
   * enough to hold this address family.
   */

  if (from)
    {
#ifdef CONFIG_NET_IPv6
      if (*fromlen < sizeof(struct sockaddr_in6))
#else
      if (*fromlen < sizeof(struct sockaddr_in))
#endif
        {
          err = EINVAL;
          goto errout;
        }
    }

  /* Set the socket state to receiving */

  psock->s_flags = _SS_SETSTATE(psock->s_flags, _SF_RECV);

  /* Perform the TCP/IP or UDP recv() operation */

#if defined(CONFIG_NET_UDP) && defined(CONFIG_NET_TCP)
  if (psock->s_type == SOCK_STREAM)
    {
      ret = tcp_recvfrom(psock, buf, len, infrom);
    }
  else
    {
      ret = udp_recvfrom(psock, buf, len, infrom);
    }
#elif defined(CONFIG_NET_TCP)
  ret = tcp_recvfrom(psock, buf, len, infrom);
#elif defined(CONFIG_NET_UDP)
  ret = udp_recvfrom(psock, buf, len, infrom);
#else
  ret = -ENOSYS;
#endif

  /* Set the socket state to idle */

  psock->s_flags = _SS_SETSTATE(psock->s_flags, _SF_IDLE);

  /* Handle returned errors */

  if (ret < 0)
    {
      err = -ret;
      goto errout;
    }

  /* Success return */

  return ret;

errout:
  errno = err;
  return ERROR;
}
예제 #17
0
static void udp_server_input_handler(evutil_socket_t fd, short what, void* arg)
{
	int cycle = 0;

	dtls_listener_relay_server_type* server = (dtls_listener_relay_server_type*) arg;

	FUNCSTART;

	if (!(what & EV_READ)) {
		return;
	}

	ioa_network_buffer_handle *elem = NULL;

	start_udp_cycle:

	elem = (ioa_network_buffer_handle *)ioa_network_buffer_allocate(server->e);

	server->sm.m.sm.nd.nbh = elem;
	server->sm.m.sm.nd.recv_ttl = TTL_IGNORE;
	server->sm.m.sm.nd.recv_tos = TOS_IGNORE;

	int slen = server->slen0;
	ssize_t bsize = 0;

	int flags = 0;

	do {
		bsize = recvfrom(fd, ioa_network_buffer_data(elem), ioa_network_buffer_get_capacity(), flags, (struct sockaddr*) &(server->sm.m.sm.nd.src_addr), (socklen_t*) &slen);
	} while (bsize < 0 && (errno == EINTR));

	int conn_reset = is_connreset();
	int to_block = would_block();

	if (bsize < 0) {

		if(to_block) {
			ioa_network_buffer_delete(server->e, server->sm.m.sm.nd.nbh);
			server->sm.m.sm.nd.nbh = NULL;
			FUNCEND;
			return;
		}

	#if defined(MSG_ERRQUEUE)

		//Linux
		int eflags = MSG_ERRQUEUE | MSG_DONTWAIT;
		static s08bits buffer[65535];
		u32bits errcode = 0;
		ioa_addr orig_addr;
		int ttl = 0;
		int tos = 0;
		udp_recvfrom(fd, &orig_addr, &(server->addr), buffer,
					(int) sizeof(buffer), &ttl, &tos, server->e->cmsg, eflags,
					&errcode);
		//try again...
		do {
			bsize = recvfrom(fd, ioa_network_buffer_data(elem), ioa_network_buffer_get_capacity(), flags, (struct sockaddr*) &(server->sm.m.sm.nd.src_addr), (socklen_t*) &slen);
		} while (bsize < 0 && (errno == EINTR));

		conn_reset = is_connreset();
		to_block = would_block();

	#endif

		if(conn_reset) {
			ioa_network_buffer_delete(server->e, server->sm.m.sm.nd.nbh);
			server->sm.m.sm.nd.nbh = NULL;
			reopen_server_socket(server);
			FUNCEND;
			return;
		}
	}

	if(bsize<0) {
		if(!to_block && !conn_reset) {
			int ern=errno;
			perror(__FUNCTION__);
			TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: recvfrom error %d\n",__FUNCTION__,ern);
		}
		ioa_network_buffer_delete(server->e, server->sm.m.sm.nd.nbh);
		server->sm.m.sm.nd.nbh = NULL;
		FUNCEND;
		return;
	}

	if (bsize > 0) {

		ioa_network_buffer_set_size(elem, (size_t)bsize);
		server->sm.m.sm.s = server->udp_listen_s;

		int rc = handle_udp_packet(server, &(server->sm), server->e, server->ts);

		if(rc < 0) {
			if(eve(server->e->verbose)) {
				TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot handle UDP event\n");
			}
		}
	}

	ioa_network_buffer_delete(server->e, server->sm.m.sm.nd.nbh);
	server->sm.m.sm.nd.nbh = NULL;

	if(cycle++<MAX_SINGLE_UDP_BATCH)
		goto start_udp_cycle;

	FUNCEND;
}
예제 #18
0
static int trfs_recv(void *pkt, int pktsize)
{
    SHOW_FLOW0( 3, "receiving" );
    return udp_recvfrom(trfs_socket, pkt, pktsize, &trfs_addr, 0, 0);
}