entouched upse_memcpy(), qse_memset().
added some code for urs
This commit is contained in:
		@ -75,7 +75,7 @@ struct urs_hdr_t
 | 
			
		||||
	qse_uint16_t seq; /* in network-byte order */
 | 
			
		||||
	qse_uint16_t rcode; /* response code */
 | 
			
		||||
	qse_uint32_t urlsum;/* checksum of url in the request */
 | 
			
		||||
	qse_uint16_t urllen; /* url length in network-byte order */
 | 
			
		||||
	qse_uint16_t pktlen; /* url length in network-byte order */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct urs_pkt_t
 | 
			
		||||
@ -85,8 +85,16 @@ struct urs_pkt_t
 | 
			
		||||
};
 | 
			
		||||
#include <qse/unpack.h>
 | 
			
		||||
 | 
			
		||||
typedef struct xpio_t xpio_t;
 | 
			
		||||
typedef struct xreq_t xreq_t;
 | 
			
		||||
struct xreq_t
 | 
			
		||||
{
 | 
			
		||||
	qse_skad_t from;
 | 
			
		||||
	qse_sck_len_t fromlen;
 | 
			
		||||
	qse_uint8_t* data;
 | 
			
		||||
	xreq_t* next;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef struct xpio_t xpio_t;
 | 
			
		||||
struct xpio_t
 | 
			
		||||
{
 | 
			
		||||
	qse_pio_t* pio;
 | 
			
		||||
@ -110,11 +118,14 @@ struct ursd_t
 | 
			
		||||
	qse_size_t nfree;
 | 
			
		||||
 | 
			
		||||
	xpio_t* xpios;
 | 
			
		||||
	xpio_t* free;
 | 
			
		||||
	xpio_t* busy;
 | 
			
		||||
	xpio_t* free_xpio;
 | 
			
		||||
	xpio_t* busy_xpio;
 | 
			
		||||
 | 
			
		||||
	qse_sck_hnd_t sck;
 | 
			
		||||
	qse_mux_t* mux;
 | 
			
		||||
 | 
			
		||||
	xreq_t* head;
 | 
			
		||||
	xreq_t* tail;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -135,16 +146,16 @@ static void chain_to_free_list (ursd_t* ursd, xpio_t* xpio)
 | 
			
		||||
{
 | 
			
		||||
	xpio->busy = 0;
 | 
			
		||||
	xpio->prev = QSE_NULL;
 | 
			
		||||
	xpio->next = ursd->free;
 | 
			
		||||
	if (ursd->free) ursd->free->prev = xpio;
 | 
			
		||||
	ursd->free = xpio;
 | 
			
		||||
	xpio->next = ursd->free_xpio;
 | 
			
		||||
	if (ursd->free_xpio) ursd->free_xpio->prev = xpio;
 | 
			
		||||
	ursd->free_xpio = xpio;
 | 
			
		||||
	ursd->nfree++;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static xpio_t* dechain_from_free_list (ursd_t* ursd, xpio_t* xpio)
 | 
			
		||||
{
 | 
			
		||||
	if (xpio->next) xpio->next->prev = xpio->prev;
 | 
			
		||||
	if (xpio == ursd->free) ursd->free = xpio->next;
 | 
			
		||||
	if (xpio == ursd->free_xpio) ursd->free_xpio = xpio->next;
 | 
			
		||||
	else xpio->prev->next = xpio->next;
 | 
			
		||||
	ursd->nfree--;
 | 
			
		||||
	return xpio;
 | 
			
		||||
@ -154,21 +165,26 @@ static void chain_to_busy_list (ursd_t* ursd, xpio_t* xpio)
 | 
			
		||||
{
 | 
			
		||||
	xpio->busy = 1;
 | 
			
		||||
	xpio->prev = QSE_NULL;
 | 
			
		||||
	xpio->next = ursd->busy;
 | 
			
		||||
	if (ursd->busy) ursd->busy->prev = xpio;
 | 
			
		||||
	ursd->busy = xpio;
 | 
			
		||||
	xpio->next = ursd->busy_xpio;
 | 
			
		||||
	if (ursd->busy_xpio) ursd->busy_xpio->prev = xpio;
 | 
			
		||||
	ursd->busy_xpio = xpio;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static xpio_t* dechain_from_busy_list (ursd_t* ursd, xpio_t* xpio)
 | 
			
		||||
{
 | 
			
		||||
	if (xpio->next) xpio->next->prev = xpio->prev;
 | 
			
		||||
 | 
			
		||||
	if (xpio == ursd->busy) ursd->busy = xpio->next;
 | 
			
		||||
	if (xpio == ursd->busy_xpio) ursd->busy_xpio = xpio->next;
 | 
			
		||||
	else xpio->prev->next = xpio->next;
 | 
			
		||||
	
 | 
			
		||||
	return xpio;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static xreq_t* enqueue_request (ursd_t* ursd, urs_pkt_t* pkt)
 | 
			
		||||
{
 | 
			
		||||
	return QSE_NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int insert_to_mux (qse_mux_t* mux, qse_mux_hnd_t handle, int type, int index)
 | 
			
		||||
{
 | 
			
		||||
	qse_mux_evt_t evt;
 | 
			
		||||
@ -191,15 +207,16 @@ static int delete_from_mux (qse_mux_t* mux, qse_mux_hnd_t handle, int type, int
 | 
			
		||||
	return qse_mux_delete (mux, &evt);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static qse_sck_hnd_t open_server_socket (int type, int proto, const qse_nwad_t* bindnwad)
 | 
			
		||||
static qse_sck_hnd_t open_server_socket (int proto, const qse_nwad_t* bindnwad)
 | 
			
		||||
{
 | 
			
		||||
	qse_sck_hnd_t s = QSE_INVALID_SCKHND;
 | 
			
		||||
	qse_skad_t skad;
 | 
			
		||||
	qse_sck_len_t skad_len;
 | 
			
		||||
	int family, flag;
 | 
			
		||||
	int family, type, flag;
 | 
			
		||||
 | 
			
		||||
	skad_len = qse_nwadtoskad (bindnwad, &skad);
 | 
			
		||||
	family = qse_skadfamily(&skad);
 | 
			
		||||
	type = (proto == IPPROTO_SCTP)? SOCK_SEQPACKET: SOCK_DGRAM;
 | 
			
		||||
 | 
			
		||||
	s = socket (family, type, proto);
 | 
			
		||||
	if (!qse_isvalidsckhnd(s))
 | 
			
		||||
@ -237,10 +254,11 @@ static qse_sck_hnd_t open_server_socket (int type, int proto, const qse_nwad_t*
 | 
			
		||||
bind_ok:
 | 
			
		||||
	if (proto == IPPROTO_SCTP)
 | 
			
		||||
	{
 | 
			
		||||
#if 0
 | 
			
		||||
#if 1
 | 
			
		||||
		struct sctp_initmsg im;
 | 
			
		||||
		struct sctp_paddrparams hb;
 | 
			
		||||
 | 
			
		||||
		memset (&im, 0, QSE_SIZEOF(im));
 | 
			
		||||
		qse_memset (&im, 0, QSE_SIZEOF(im));
 | 
			
		||||
		im.sinit_num_ostreams = 1;
 | 
			
		||||
		im.sinit_max_instreams = 1;
 | 
			
		||||
		im.sinit_max_attempts = 1;
 | 
			
		||||
@ -250,6 +268,13 @@ bind_ok:
 | 
			
		||||
			fprintf (stderr, "cannot set sctp initmsg option\n");
 | 
			
		||||
			goto oops;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		qse_memset (&hb, 0, QSE_SIZEOF(hb));
 | 
			
		||||
		hb.spp_flags = SPP_HB_ENABLE;
 | 
			
		||||
		hb.spp_hbinterval = 5000;
 | 
			
		||||
		hb.spp_pathmaxrxt = 1;
 | 
			
		||||
 | 
			
		||||
		if (setsockopt (s, SOL_SCTP, SCTP_PEER_ADDR_PARAMS, &hb, QSE_SIZEOF(hb)) <= -1) goto oops;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
		if (listen (s, 99) <= -1)
 | 
			
		||||
@ -266,18 +291,18 @@ oops:
 | 
			
		||||
	return QSE_INVALID_SCKHND;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void schedule_request (ursd_t* ursd, urs_pkt_t* pkt, int pktsize, const qse_skad_t* skad, qse_sck_len_t skadlen)
 | 
			
		||||
static void schedule_request (ursd_t* ursd, urs_pkt_t* pkt, const qse_skad_t* skad, qse_sck_len_t skadlen)
 | 
			
		||||
{
 | 
			
		||||
	if (ursd->free)
 | 
			
		||||
	if (ursd->free_xpio)
 | 
			
		||||
	{
 | 
			
		||||
		xpio_t* xpio = dechain_from_free_list (ursd, ursd->free);
 | 
			
		||||
		xpio_t* xpio = dechain_from_free_list (ursd, ursd->free_xpio);
 | 
			
		||||
 | 
			
		||||
		xpio->req.from = *skad;
 | 
			
		||||
		xpio->req.fromlen = skadlen;
 | 
			
		||||
		memcpy (xpio->req.buf, pkt, QSE_SIZEOF(urs_hdr_t)); /* copy header */
 | 
			
		||||
printf ("XPIO WRITNG TO PIPE %p %d\n", xpio, qse_skadfamily(skad));
 | 
			
		||||
		qse_pio_write (xpio->pio, QSE_PIO_IN, pkt->url, qse_ntoh16(pkt->hdr.urllen)); /* TODO: erro ahndlig */
 | 
			
		||||
		qse_memcpy (xpio->req.buf, pkt, QSE_SIZEOF(urs_hdr_t)); /* copy header */
 | 
			
		||||
 | 
			
		||||
printf ("XPIO WRITNG TO PIPE %p %d\n", xpio, qse_skadfamily(skad));
 | 
			
		||||
		qse_pio_write (xpio->pio, QSE_PIO_IN, pkt->url, pkt->hdr.pktlen - QSE_SIZEOF(urs_hdr_t)); /* TODO: error handling */
 | 
			
		||||
		chain_to_busy_list (ursd, xpio);
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
@ -306,17 +331,20 @@ static void dispatch_mux_event (qse_mux_t* mux, const qse_mux_evt_t* evt)
 | 
			
		||||
	{
 | 
			
		||||
		ssize_t x;
 | 
			
		||||
 | 
			
		||||
		skad_len = QSE_SIZEOF(skad);
 | 
			
		||||
		x = recvfrom (evt->hnd, buf, QSE_SIZEOF(buf), 0, (struct sockaddr*)&skad, &skad_len);
 | 
			
		||||
 | 
			
		||||
printf ("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXx\n");
 | 
			
		||||
/* TODO: error handling */
 | 
			
		||||
		if (x >= QSE_SIZEOF(urs_hdr_t))
 | 
			
		||||
		{
 | 
			
		||||
			urs_pkt_t* pkt = (urs_pkt_t*)buf;
 | 
			
		||||
			qse_uint16_t len = qse_ntoh16(pkt->hdr.urllen);
 | 
			
		||||
 | 
			
		||||
			if (QSE_SIZEOF(urs_hdr_t) + len == x)
 | 
			
		||||
			pkt->hdr.pktlen = qse_ntoh16(pkt->hdr.pktlen); /* change the byte order */
 | 
			
		||||
			if (pkt->hdr.pktlen == x)
 | 
			
		||||
			{
 | 
			
		||||
				printf ("%d %d [[[%s]]]\n", len, x, pkt->url);
 | 
			
		||||
				schedule_request (mux_xtn->ursd, pkt, x, &skad, skad_len);
 | 
			
		||||
				printf ("%d [[[%.*s]]]\n", (int)x, (int)(pkt->hdr.pktlen - QSE_SIZEOF(urs_hdr_t)), pkt->url);
 | 
			
		||||
				schedule_request (mux_xtn->ursd, pkt, &skad, skad_len);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
@ -326,21 +354,36 @@ static void dispatch_mux_event (qse_mux_t* mux, const qse_mux_evt_t* evt)
 | 
			
		||||
		urs_pkt_t* pkt;
 | 
			
		||||
		xpio_t* xpio = &mux_xtn->ursd->xpios[index];
 | 
			
		||||
 | 
			
		||||
		pkt = (urs_pkt_t*)xpio->req.buf;
 | 
			
		||||
printf ("XPIO READING TO PIPE %p\n", xpio);
 | 
			
		||||
		x = qse_pio_read (xpio->pio, QSE_PIO_OUT, pkt->url, QSE_SIZEOF(xpio->req.buf) - QSE_SIZEOF(urs_hdr_t));
 | 
			
		||||
 | 
			
		||||
		pkt->hdr.urllen = qse_hton16(x);
 | 
			
		||||
printf ("READ %d bytes from pipes [%s]\n", x, pkt->url);
 | 
			
		||||
		sendto (mux_xtn->ursd->sck, pkt, QSE_SIZEOF(urs_hdr_t) + x, 0, &xpio->req.from, xpio->req.fromlen);
 | 
			
		||||
 | 
			
		||||
/* TODO: error handling */
 | 
			
		||||
 | 
			
		||||
		if (xpio->busy)
 | 
			
		||||
		{
 | 
			
		||||
			pkt = (urs_pkt_t*)xpio->req.buf;
 | 
			
		||||
 | 
			
		||||
			x = qse_pio_read (xpio->pio, QSE_PIO_OUT, pkt->url, QSE_SIZEOF(xpio->req.buf) - QSE_SIZEOF(urs_hdr_t));
 | 
			
		||||
printf ("READ %d bytes from pipes [%.*s]\n", (int)x, (int)x, pkt->url);
 | 
			
		||||
 | 
			
		||||
			x += QSE_SIZEOF(urs_hdr_t); /* add up the header size */
 | 
			
		||||
			if (x > QSE_TYPE_MAX(qse_uint16_t))
 | 
			
		||||
			{
 | 
			
		||||
				/* ERROR HANDLING - it's returning too long data */
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			pkt->hdr.pktlen = qse_hton16(x); /* change the byte order */
 | 
			
		||||
			sendto (mux_xtn->ursd->sck, pkt, x, 0, (struct sockaddr*)&xpio->req.from, xpio->req.fromlen);
 | 
			
		||||
 | 
			
		||||
	/* TODO: error handling */
 | 
			
		||||
 | 
			
		||||
			/* TODO: if there is a pending request, use this xpio to send request... */
 | 
			
		||||
 | 
			
		||||
			dechain_from_busy_list (mux_xtn->ursd, xpio);
 | 
			
		||||
			chain_to_free_list (mux_xtn->ursd, xpio);
 | 
			
		||||
		}
 | 
			
		||||
		else 
 | 
			
		||||
		{
 | 
			
		||||
			/* something is wrong. if the child process writes something 
 | 
			
		||||
			 * while it's not given any input. restart this process */
 | 
			
		||||
 | 
			
		||||
			/* TODO: */
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -365,7 +408,7 @@ static int init_ursd (ursd_t* ursd, int npios, const qse_char_t* cmdline, const
 | 
			
		||||
		goto oops;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ursd->sck = open_server_socket (SOCK_SEQPACKET, IPPROTO_SCTP, &bindnwad);
 | 
			
		||||
	ursd->sck = open_server_socket (/*IPPROTO_SCTP*/IPPROTO_UDP, &bindnwad);
 | 
			
		||||
 | 
			
		||||
	ursd->xpios = calloc (npios, QSE_SIZEOF(xpio_t));
 | 
			
		||||
	if (ursd->xpios == QSE_NULL) 
 | 
			
		||||
@ -508,7 +551,6 @@ int qse_main (int argc, qse_achar_t* argv[])
 | 
			
		||||
	qse_closestdsios ();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#if defined(_WIN32)
 | 
			
		||||
	WSACleanup ();
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@ -85,8 +85,91 @@ void* qse_memcpy (void* dst, const void* src, qse_size_t n)
 | 
			
		||||
	while (n-- > 0) *d++ = *s++;
 | 
			
		||||
	return dst;
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
#elif defined(__GNUC__) && (defined(__x86_64) || defined(__amd64))
 | 
			
		||||
 | 
			
		||||
	/* i don't really care about alignments for x86-64 at this moment. fix it later */
 | 
			
		||||
 | 
			
		||||
	__asm__ volatile (
 | 
			
		||||
		"cld\n\t"
 | 
			
		||||
		"rep movsq\n"
 | 
			
		||||
		: /* no output */
 | 
			
		||||
		:"D" (dst), "S" (src), "c" (n >> 3)  /* input: %rdi = d, %rsi = src, %rcx = n / 8 */
 | 
			
		||||
		:"memory"
 | 
			
		||||
	);
 | 
			
		||||
 | 
			
		||||
	__asm__ volatile (
 | 
			
		||||
		"rep movsb\n" 
 | 
			
		||||
		: /* no output */
 | 
			
		||||
		:"c" (n & 7)  /* %rcx = n % 8, use existing %rdi and %rsi */
 | 
			
		||||
		:"memory", "%rdi", "%rsi"
 | 
			
		||||
	);
 | 
			
		||||
 | 
			
		||||
	return dst;
 | 
			
		||||
 | 
			
		||||
	#if 0
 | 
			
		||||
	qse_byte_t* d = dst;
 | 
			
		||||
 | 
			
		||||
	__asm__ volatile (
 | 
			
		||||
		"cld\n\t"
 | 
			
		||||
		"rep movsq\n"
 | 
			
		||||
		: "=D" (d), "=S" (src)  /* output: d = %rdi, src = %rsi */
 | 
			
		||||
		:"0" (d), "1" (src), "c" (n >> 3)  /* input: %rdi = d, %rsi = src, %rcx = n / 8 */
 | 
			
		||||
		:"memory"
 | 
			
		||||
	);
 | 
			
		||||
 | 
			
		||||
	__asm__ volatile (
 | 
			
		||||
		"rep movsb"
 | 
			
		||||
		: /* no output */
 | 
			
		||||
		:"D" (d), "S" (src), "c" (n & 7)  /* input: %rdi = d, %rsi = src, %rcx = n % 8 */
 | 
			
		||||
		:"memory"
 | 
			
		||||
	);
 | 
			
		||||
 | 
			
		||||
	return dst;
 | 
			
		||||
	#endif
 | 
			
		||||
 | 
			
		||||
#elif defined(__GNUC__) && (defined(__i386) || defined(i386))
 | 
			
		||||
 | 
			
		||||
	/* i don't really care about alignments for x86 at this moment. fix it later */
 | 
			
		||||
 | 
			
		||||
	__asm__ volatile (
 | 
			
		||||
		"cld\n\t"
 | 
			
		||||
		"rep movsl\n"
 | 
			
		||||
		: /* no output */
 | 
			
		||||
		:"D" (dst), "S" (src), "c" (n >> 2)  /* input: %edi = d, %esi = src, %ecx = n / 8 */
 | 
			
		||||
		:"memory"
 | 
			
		||||
	);
 | 
			
		||||
 | 
			
		||||
	__asm__ volatile (
 | 
			
		||||
		"rep movsb\n" 
 | 
			
		||||
		: /* no output */
 | 
			
		||||
		:"c" (n & 3)  /* %rcx = n % 8, use existing %edi and %esi */
 | 
			
		||||
		:"memory", "%edi", "%esi"
 | 
			
		||||
	);
 | 
			
		||||
 | 
			
		||||
	return dst;
 | 
			
		||||
 | 
			
		||||
	#if 0
 | 
			
		||||
	qse_byte_t* d = dst;
 | 
			
		||||
 | 
			
		||||
	__asm__ volatile (
 | 
			
		||||
		"cld\n\t"
 | 
			
		||||
		"rep movsl\n"
 | 
			
		||||
		:"=D" (d), "=S" (src) /* output: d = %edi, src = %esi */
 | 
			
		||||
		:"0" (d), "1" (src), "c" (n >> 2)  /* input: %edi = d, %esi = src, %ecx = n / 4 */
 | 
			
		||||
		:"memory"
 | 
			
		||||
	);
 | 
			
		||||
 | 
			
		||||
	__asm__ volatile (
 | 
			
		||||
		"rep movsb\n"
 | 
			
		||||
		:
 | 
			
		||||
		:"D" (d), "S" (src), "c" (n & 3)  /* input: %edi = d, %esi = src, %ecx = n % 4 */
 | 
			
		||||
		:"memory"
 | 
			
		||||
	);
 | 
			
		||||
 | 
			
		||||
	return dst;
 | 
			
		||||
	#endif
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
	qse_byte_t* d;
 | 
			
		||||
	qse_byte_t* s;
 | 
			
		||||
 | 
			
		||||
@ -207,8 +290,81 @@ void* qse_memset (void* dst, int val, qse_size_t n)
 | 
			
		||||
	while (n-- > 0) *d++ = (qse_byte_t)val;
 | 
			
		||||
	return dst;
 | 
			
		||||
	
 | 
			
		||||
#else
 | 
			
		||||
#elif defined(__GNUC__) && (defined(__x86_64) || defined(__amd64))
 | 
			
		||||
 | 
			
		||||
	/* i don't really care about alignments for x86-64 at this moment. fix it later */
 | 
			
		||||
 | 
			
		||||
	qse_byte_t* d = dst;
 | 
			
		||||
 | 
			
		||||
	__asm__ volatile ("cld\n");
 | 
			
		||||
 | 
			
		||||
	if (n >= 8)
 | 
			
		||||
	{
 | 
			
		||||
		qse_size_t qw = (qse_byte_t)val;
 | 
			
		||||
		if (qw)
 | 
			
		||||
		{
 | 
			
		||||
			qw = (qw << 8) | (qse_byte_t)val;
 | 
			
		||||
			qw = (qw << 8) | (qse_byte_t)val;
 | 
			
		||||
			qw = (qw << 8) | (qse_byte_t)val;
 | 
			
		||||
			qw = (qw << 8) | (qse_byte_t)val;
 | 
			
		||||
			qw = (qw << 8) | (qse_byte_t)val;
 | 
			
		||||
			qw = (qw << 8) | (qse_byte_t)val;
 | 
			
		||||
			qw = (qw << 8) | (qse_byte_t)val;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		__asm__ volatile (
 | 
			
		||||
			"rep stosq\n"
 | 
			
		||||
			:"=D" (d) /* output: d = %rdi */
 | 
			
		||||
			:"0" (d), "a" (qw), "c" (n >> 3)  /* input: %rdi = d, %rax = qw, %rcx = n / 8 */
 | 
			
		||||
			:"memory"
 | 
			
		||||
		);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	__asm__ volatile (
 | 
			
		||||
		"rep stosb\n"
 | 
			
		||||
		: /* no output */
 | 
			
		||||
		:"D" (d), "a" (val), "c" (n & 7)  /* input: %rdi = d, %rax = src, %rcx = n % 8 */
 | 
			
		||||
		:"memory"
 | 
			
		||||
	);
 | 
			
		||||
 | 
			
		||||
	return dst;
 | 
			
		||||
 | 
			
		||||
#elif defined(__GNUC__) && (defined(__i386) || defined(i386))
 | 
			
		||||
 | 
			
		||||
	/* i don't really care about alignments for x86 at this moment. fix it later */
 | 
			
		||||
 | 
			
		||||
	qse_byte_t* d = dst;
 | 
			
		||||
 | 
			
		||||
	__asm__ volatile ("cld\n");
 | 
			
		||||
 | 
			
		||||
	if (n >= 4)
 | 
			
		||||
	{
 | 
			
		||||
		qse_size_t dw = (qse_byte_t)val;
 | 
			
		||||
		if (dw)
 | 
			
		||||
		{
 | 
			
		||||
			dw = (dw << 8) | (qse_byte_t)val;
 | 
			
		||||
			dw = (dw << 8) | (qse_byte_t)val;
 | 
			
		||||
			dw = (dw << 8) | (qse_byte_t)val;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		__asm__ volatile (
 | 
			
		||||
			"rep stosl\n"
 | 
			
		||||
			:"=D" (d) /* output: d = %edi */
 | 
			
		||||
			:"0" (d), "a" (dw), "c" (n >> 2)  /* input: %edi = d, %eax = dw, %ecx = n / 4 */
 | 
			
		||||
			:"memory"
 | 
			
		||||
		);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	__asm__ volatile (
 | 
			
		||||
		"rep stosb\n"
 | 
			
		||||
		: /* no output */ 
 | 
			
		||||
		:"D" (d), "a" (val), "c" (n & 3)  /* input: %edi = d, %eax = src, %ecx = n % 4 */
 | 
			
		||||
		:"memory"
 | 
			
		||||
	);
 | 
			
		||||
 | 
			
		||||
	return dst;
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
	qse_byte_t* d;
 | 
			
		||||
	qse_size_t rem;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -36,7 +36,7 @@ struct urs_hdr_t
 | 
			
		||||
	qse_uint16_t seq;    /* in network-byte order */
 | 
			
		||||
	qse_uint16_t rcode;  /* response code */
 | 
			
		||||
	qse_uint32_t urlsum; /* checksum of url in the request */
 | 
			
		||||
	qse_uint16_t urllen; /* url length in network-byte order */
 | 
			
		||||
	qse_uint16_t pktlen; /* packet header size + url length */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct urs_pkt_t
 | 
			
		||||
@ -59,8 +59,8 @@ struct urs_ctx_t
 | 
			
		||||
	urs_req_t* reqs[1024]; /* TOOD: choose the right size */
 | 
			
		||||
	qse_uint16_t req_count;
 | 
			
		||||
 | 
			
		||||
	qse_uint8_t rcvbuf[URS_MAX_URL_LEN + QSE_SIZEOF(urs_pkt_t)];
 | 
			
		||||
	qse_uint8_t fmtbuf[URS_MAX_URL_LEN + QSE_SIZEOF(urs_pkt_t)];
 | 
			
		||||
	qse_uint8_t rcvbuf[QSE_SIZEOF(urs_hdr_t) + URS_MAX_URL_LEN + 1];
 | 
			
		||||
	qse_uint8_t fmtbuf[QSE_SIZEOF(urs_hdr_t) + URS_MAX_URL_LEN + 1];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct urs_req_t
 | 
			
		||||
@ -95,7 +95,7 @@ static int urs_open (qse_httpd_t* httpd, qse_httpd_urs_t* urs)
 | 
			
		||||
	qse_nwad_t nwad;
 | 
			
		||||
	urs_ctx_t* dc;
 | 
			
		||||
	httpd_xtn_t* httpd_xtn;
 | 
			
		||||
	int type, proto = IPPROTO_SCTP;
 | 
			
		||||
	int type, proto = IPPROTO_UDP; //IPPROTO_SCTP;
 | 
			
		||||
 | 
			
		||||
	httpd_xtn = qse_httpd_getxtn (httpd);
 | 
			
		||||
 | 
			
		||||
@ -147,12 +147,14 @@ static int urs_open (qse_httpd_t* httpd, qse_httpd_urs_t* urs)
 | 
			
		||||
		dc->urs_socket = QSE_INVALID_SCKHND;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
#if 0
 | 
			
		||||
	if (proto == IPPROTO_SCTP)
 | 
			
		||||
	{
 | 
			
		||||
/* TODO: error ahndleing */
 | 
			
		||||
		if (qse_isvalidsckhnd(urs->handle[0].i)) listen (urs->handle[0].i, 99);
 | 
			
		||||
		if (qse_isvalidsckhnd(urs->handle[1].i)) listen (urs->handle[1].i, 99);
 | 
			
		||||
	}
 | 
			
		||||
#endif
 | 
			
		||||
	urs->handle_count = 2;
 | 
			
		||||
 | 
			
		||||
	urs->ctx = dc;
 | 
			
		||||
@ -215,7 +217,7 @@ static int urs_recv (qse_httpd_t* httpd, qse_httpd_urs_t* urs, qse_ubi_t handle)
 | 
			
		||||
	socklen_t fromlen;
 | 
			
		||||
 | 
			
		||||
	qse_uint16_t xid;
 | 
			
		||||
	qse_ssize_t len;
 | 
			
		||||
	qse_ssize_t len, url_len;
 | 
			
		||||
	urs_pkt_t* pkt;
 | 
			
		||||
	urs_req_t* req;
 | 
			
		||||
 | 
			
		||||
@ -229,8 +231,12 @@ printf ("URS_RECV....\n");
 | 
			
		||||
/* TODO: check if fromaddr matches the dc->skad... */
 | 
			
		||||
 | 
			
		||||
	pkt = (urs_pkt_t*)dc->rcvbuf;
 | 
			
		||||
	if (len >= QSE_SIZEOF(pkt->hdr) &&  len >= QSE_SIZEOF(pkt->hdr) + qse_ntoh16(pkt->hdr.urllen))
 | 
			
		||||
	if (len >= QSE_SIZEOF(urs_hdr_t))
 | 
			
		||||
	{
 | 
			
		||||
		pkt->hdr.pktlen = qse_ntoh16(pkt->hdr.pktlen);
 | 
			
		||||
		if (len == pkt->hdr.pktlen)
 | 
			
		||||
		{
 | 
			
		||||
			url_len = pkt->hdr.pktlen - QSE_SIZEOF(urs_hdr_t);
 | 
			
		||||
			xid = qse_ntoh16(pkt->hdr.seq) % QSE_COUNTOF(dc->reqs);
 | 
			
		||||
 | 
			
		||||
			for (req = dc->reqs[xid]; req; req = req->next)
 | 
			
		||||
@ -238,7 +244,7 @@ printf ("URS_RECV....\n");
 | 
			
		||||
				if (req->pkt->hdr.seq == pkt->hdr.seq && req->pkt->hdr.urlsum == pkt->hdr.urlsum)
 | 
			
		||||
				{
 | 
			
		||||
					/* null-terminate the url for easier processing */
 | 
			
		||||
				pkt->url[qse_ntoh16(pkt->hdr.urllen)] = QSE_MT('\0');
 | 
			
		||||
					pkt->url[url_len] = QSE_MT('\0');
 | 
			
		||||
 | 
			
		||||
					urs_remove_tmr_tmout (httpd, req);
 | 
			
		||||
					req->rewrite (httpd, req->pkt->url, pkt->url, req->ctx);
 | 
			
		||||
@ -255,6 +261,7 @@ printf ("URS_RECV....\n");
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
@ -362,21 +369,19 @@ static int urs_send (qse_httpd_t* httpd, qse_httpd_urs_t* urs, const qse_mchar_t
 | 
			
		||||
 | 
			
		||||
	xid = seq % QSE_COUNTOF(dc->reqs); 
 | 
			
		||||
 | 
			
		||||
	req = qse_httpd_callocmem (httpd, QSE_SIZEOF(*req) + url_len + QSE_SIZEOF(urs_pkt_t));
 | 
			
		||||
	req = qse_httpd_callocmem (httpd, QSE_SIZEOF(*req) + QSE_SIZEOF(urs_hdr_t) + url_len + 1);
 | 
			
		||||
	if (req == QSE_NULL) goto oops;
 | 
			
		||||
 | 
			
		||||
	req->tmr_tmout = QSE_TMR_INVALID_INDEX;
 | 
			
		||||
	req->seq = seq;
 | 
			
		||||
	req->pkt = (urs_pkt_t*)(req + 1);
 | 
			
		||||
	req->pktlen = QSE_SIZEOF(urs_hdr_t) + url_len;
 | 
			
		||||
 | 
			
		||||
	req->pkt->hdr.seq = qse_hton16(seq);
 | 
			
		||||
	req->pkt->hdr.urllen = qse_hton16(url_len);
 | 
			
		||||
	req->pkt->hdr.pktlen = qse_hton16(req->pktlen);
 | 
			
		||||
	req->pkt->hdr.urlsum = hash_string (url);
 | 
			
		||||
	qse_mbscpy (req->pkt->url, url);
 | 
			
		||||
 | 
			
		||||
	/* -1 to exclude the terminating '\0' as urs_pkt_t has url[1]. */
 | 
			
		||||
	req->pktlen = QSE_SIZEOF(urs_pkt_t) + url_len - 1; 
 | 
			
		||||
 | 
			
		||||
	req->rewrite = rewrite;
 | 
			
		||||
	req->ctx = ctx;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -730,10 +730,11 @@ static qse_sck_hnd_t open_udp_socket (qse_httpd_t* httpd, int domain, int type,
 | 
			
		||||
 | 
			
		||||
	if (set_socket_nonblock (httpd, fd, 1) <= -1) goto oops;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#if 1
 | 
			
		||||
	if (proto == IPPROTO_SCTP)
 | 
			
		||||
	{
 | 
			
		||||
		struct sctp_initmsg im;
 | 
			
		||||
		struct sctp_paddrparams hb;
 | 
			
		||||
 | 
			
		||||
		QSE_MEMSET (&im, 0, QSE_SIZEOF(im));
 | 
			
		||||
		im.sinit_num_ostreams = 1;
 | 
			
		||||
@ -741,7 +742,15 @@ static qse_sck_hnd_t open_udp_socket (qse_httpd_t* httpd, int domain, int type,
 | 
			
		||||
		im.sinit_max_attempts = 1;
 | 
			
		||||
 | 
			
		||||
		if (setsockopt (fd, SOL_SCTP, SCTP_INITMSG, &im, QSE_SIZEOF(im)) <= -1) goto oops;
 | 
			
		||||
 | 
			
		||||
		QSE_MEMSET (&hb, 0, QSE_SIZEOF(hb));
 | 
			
		||||
		hb.spp_flags = SPP_HB_ENABLE;
 | 
			
		||||
		hb.spp_hbinterval = 5000;
 | 
			
		||||
		hb.spp_pathmaxrxt = 1;
 | 
			
		||||
 | 
			
		||||
		if (setsockopt (fd, SOL_SCTP, SCTP_PEER_ADDR_PARAMS, &hb, QSE_SIZEOF(hb)) <= -1) goto oops;
 | 
			
		||||
	}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	return fd;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user