]> git.lizzy.rs Git - rudp.git/blob - rudp.c
Switch to CMake
[rudp.git] / rudp.c
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include "rudp_imp.h"
4 #include "rudp.h"
5 #include "crc32.h"
6
7 #include <assert.h>
8
9 #ifndef min
10 #define min(x,y) ((x)<(y)?(x):(y))
11 #endif
12 #ifndef max
13 #define max(x,y) ((x)>(y)?(x):(y))
14 #endif
15
16 #ifndef offsetof
17 #define offsetof(s, m) ((int)(&((s*)0)->m))
18 #endif
19
20 #if defined(_WIN32) || defined(ARM_UCOS_LWIP)
21 #define SETEVENT(event) PA_SetEvent(event)
22 #elif defined(__linux__)
23 #define SETEVENT(event) pthread_cond_signal(&event)
24 #endif
25 #define SAFE_FREE(p) if(p) { free(p); p = NULL; }
26 //---------------------------------------------------------
27 PA_MUTEX        mutex_sock_list;
28 LIST_HEAD(sock_list);
29
30 PA_HTHREAD hthd;
31 static volatile int run = 1;
32
33 static PA_MUTEX mutex_pkt_pool;
34 static int n_free_pkt = 0;
35 static struct rudp_pkt *free_pkt = NULL;
36
37 //static int sockw_r = -1, sockw_s;
38 struct output_notify {
39         struct rudp_socket *s;
40         int chno;
41 };
42
43 unsigned int rudp_now = 0;
44 //==========================================================
45
46
47 #define RO_NORMAL       0
48 #define RO_FORCE        1
49 #define RO_REXMT        2   //rexmt as RCT_REXMT timer
50 #define RO_ONLYONE      3
51 #define RO_REXMT_FAST 4 //rexmt as duplicated ack received
52
53 #define INITIAL_SEQ_NO  0
54
55 #define FASTRETRANS     0
56 #define FASTRETRANS2    1       //multiple packet lost
57 #define CONGESTED       2
58
59 //value for should_ack
60 #define ACKT_DELAYED    1
61 #define ACKT_OPENWND    2
62
63 #ifdef _DEBUG_RUDP
64 static char* IP2STR(unsigned int ip, char ips[16])
65 {
66         int len = sprintf(ips, "%d.", ip&0xFF);
67         len += sprintf(ips+len, "%d.", (ip>>8)&0xFF);
68         len += sprintf(ips+len, "%d.", (ip>>16)&0xFF);
69         len += sprintf(ips+len, "%d", (ip>>24)&0xFF);
70         return ips;
71 }
72
73 static void _printTime()
74 {
75         char sf[16];
76 #if defined(ARM_UCOS_LWIP)
77 #elif defined(_WIN32)
78         SYSTEMTIME t;
79         GetLocalTime(&t);
80         sprintf(sf, "%.06f", t.wMilliseconds/1000.0);
81         PRINTF("%02d:%02d:%02d.%s  ", t.wHour, t.wMinute, t.wSecond, sf+2);
82 #else
83         struct timeval tv;
84         struct tm _tm;
85         gettimeofday(&tv, NULL);
86         localtime_r(&tv.tv_sec, &_tm);
87         sprintf(sf, "%.06f", tv.tv_usec/1000000.0);
88         PRINTF("%02d:%02d:%02d.%s  ", _tm.tm_hour, _tm.tm_min, _tm.tm_sec, sf+2);
89 #endif
90 }
91 #define PHF_FROM        0x10000000
92 #define PHF_DATA        0x20000000
93 static void __printHdr(const struct rudp_pcb *pcb, const struct rudp_hdr *phdr, const struct sockaddr_in *pa, int phf, int data_len)
94 {
95         char ip[16];
96         _printTime();
97         if(phf & PHF_FROM)
98         {
99                 PRINTF("%s.%d > ", IP2STR(pa->sin_addr.s_addr, ip), (int)ntohs(pa->sin_port));
100                 if(pcb) PRINTF("%s.%d ", IP2STR(pcb->local.sin_addr.s_addr, ip), (int)ntohs(pcb->local.sin_port));
101         }
102         else
103         {
104                 if(pcb) PRINTF("%s.%d > ", IP2STR(pcb->local.sin_addr.s_addr, ip), (int)ntohs(pcb->local.sin_port));
105                 PRINTF("%s.%d ", IP2STR(pa->sin_addr.s_addr, ip), (int)ntohs(pa->sin_port));
106         }
107         PRINTF("c:%d ", phdr->flags.chno);
108
109         if(data_len) 
110         {
111                 PRINTF("P s:%u(%d) ", ntohl(phdr->seqno), data_len);
112         }
113         else printf(". ");
114         if(phdr->flags.syn) PRINTF("syn ");
115         if(phdr->flags.ack) PRINTF("ack %u(%d) ", ntohl(phdr->ackno), phdr->flags.n_loss);
116         if(phdr->flags.rst) PRINTF("rst ");
117         if(phdr->flags.fin) PRINTF("fin ");
118         PRINTF("win %d ", (int)WINDOW_NTOH(phdr->flags.window));
119
120         if(pcb)
121         {
122                 PRINTF("[rwnd %d cwnd %d ssth %d", pcb->channel[phdr->flags.chno].sbuf.rwnd, pcb->cwnd, pcb->ssthresh);
123                 if(phdr->flags.ack && (phf&PHF_FROM))
124                 {
125                         PRINTF(" rto %d", pcb->rto);
126                         PRINTF(" rtw %d", pcb->rtw_size);
127                         if(phdr->flags.n_loss) PRINTF(" lost %d", phdr->flags.n_loss);
128                 }
129                 PRINTF(" una %d", pcb->channel[phdr->flags.chno].sbuf.n_unacked);
130                 PRINTF("]");
131         }
132         PRINTF("\n");
133 #if defined(_WIN32)
134         fflush(stdout);
135 #endif
136 }
137 static void _printHdr(const struct rudp_pcb *pcb, const struct rudp_hdr *phdr, const struct sockaddr_in *pa)
138 {
139         __printHdr(pcb, phdr, pa, 0, 0);
140 }
141 static void _printPkt(const struct rudp_pcb *pcb, const struct rudp_pkt *pkt, int phf, const struct sockaddr_in *pa)
142 {
143         if(pkt->len) { phf |= PHF_DATA; }
144         __printHdr(pcb, &pkt->hdr, pa, phf, pkt->len);
145 }
146 #else
147 #define _printHdr(a,b,c)
148 #define _printPkt(a,b,c,d)
149 #define _printTime()
150 #endif
151
152 #define DELAY_ACK_MS    100
153 #define RTT_UINT        200                     //accuracy of RTT, ms
154 #define RTT_MIN         (1000/RTT_UINT)         //count in 1 second.
155
156 #define MAX_REXMT_ATTEMPT       6       
157 static int rudp_backoff[MAX_REXMT_ATTEMPT+1] = { 1, 2, 4, 8, 16, 32, 32/*, 64, 64, 64, 64, 64*/ };
158 #define MAX_RECONN_ATTEMPT      5
159 static int conn_backoff[MAX_RECONN_ATTEMPT+1] = { RTT_MIN, 1*RTT_MIN, 2*RTT_MIN, 2*RTT_MIN, 2*RTT_MIN, 2*RTT_MIN };     //s
160
161 static struct rudp_pkt *_MBufGetPacket();
162 static void _MBufPutPacket(struct rudp_pkt *pkt);
163 static int _ProcessPacket(struct rudp_socket *s, struct rudp_pkt *pkt, const struct sockaddr *from, int from_len);
164 int _DispatchPacket(struct rudp_socket *s, struct rudp_pkt *pkt, const struct sockaddr *from, int from_len);
165 static INLINE void _sendPacket(struct rudp_socket *s, struct rudp_channel *pch, struct rudp_pkt *pkt, int opt);
166 static void _sendReset(struct rudp_socket *s, const struct sockaddr *to);
167 static /*INLINE */void _sendHeader(struct rudp_socket *s, struct rudp_hdr *phdr);
168 static void _sendSyn(struct rudp_socket *s);
169 static void _sendSynAck(struct rudp_socket *s);
170 static void _sendAck(struct rudp_socket *s, int chno);
171 static void _sendFin(struct rudp_socket *s);
172
173 typedef void (*TimerHandler)(struct rudp_socket *s);
174 static void _timerProc(TimerHandler handler);
175 static void _handleTimer500ms(struct rudp_socket *s);
176 static void _handleTimer200ms(struct rudp_socket *s);
177
178 static struct rudp_pkt *_MBufGetPacket()
179 {
180         struct rudp_pkt *p;
181
182         PA_MutexLock(mutex_pkt_pool);
183         if(free_pkt)
184         {
185                 p = free_pkt;
186                 free_pkt = free_pkt->next;
187                 n_free_pkt --;
188         }
189         else
190         {
191                 p = (struct rudp_pkt*)malloc(sizeof(struct rudp_pkt));
192                 if(!p) {
193                         PA_MutexUnlock(mutex_pkt_pool);
194                         return NULL;
195                 }
196         }
197         p->next = NULL;
198         p->hdr.u32_flags = 0;
199         p->hdr.flags.rudp = RUDP_HEADER_TAG;
200         p->len = 0;
201         p->trans = 0;
202         p->pdata = p->data;
203         PA_MutexUnlock(mutex_pkt_pool);
204
205         return p;
206 }
207 static void _MBufPutPacket(struct rudp_pkt *pkt)
208 {
209         PA_MutexLock(mutex_pkt_pool);
210         if(n_free_pkt > 256)
211         {
212                 free(pkt);
213         }
214         else
215         {
216                 pkt->next = free_pkt;
217                 free_pkt = pkt;
218                 n_free_pkt++;
219         }
220         PA_MutexUnlock(mutex_pkt_pool);
221 }
222
223 static struct rudp_socket *_AllocRudpSocket()
224 {
225         struct rudp_socket *sock = (struct rudp_socket*)calloc(sizeof(struct rudp_socket), 1);
226         sock->tag = RUDP_SOCKET_TAG;
227
228         sock->state = RS_CLOSED;
229         sock->rcvbuf_sz = DEFAULT_RCVBUF_SIZE;
230
231         PA_MutexInit(sock->mutex_r);
232         PA_MutexInit(sock->mutex_w);
233 #if defined(_WIN32) || defined(ARM_UCOS_LWIP)
234         PA_EventInit(sock->event_r);
235         PA_EventInit(sock->event_w);
236 #else
237         pthread_cond_init(&sock->event_r, NULL);
238         pthread_cond_init(&sock->event_w, NULL);
239 #endif
240
241         INIT_LIST_HEAD(&sock->inst_list);
242         INIT_LIST_HEAD(&sock->listen_queue);
243         INIT_LIST_HEAD(&sock->accepted_list);
244         return sock;
245 }
246
247 static struct rudp_pcb *_AllocRudpPcb(uint32_t rcvbuf_size, uint32_t initial_seqno, uint32_t peer_initial_seqno, int rawnd)
248 {
249         struct rudp_pcb *pcb;
250         int i;
251         pcb = (struct rudp_pcb*)calloc(sizeof(struct rudp_pcb), 1);
252         for(i=0; i<MAX_PHY_CHANNELS; i++)
253         {
254                 struct sndbuf *psbuf;
255                 struct rcvbuf *prbuf;
256                 
257                 psbuf = &pcb->channel[i].sbuf;
258                 psbuf->seqno = initial_seqno;
259                 psbuf->max_pkts = DEFAULT_SNDBUF_SIZE;
260                 psbuf->rwnd = psbuf->rawnd = rawnd;
261
262                 prbuf = &pcb->channel[i].rbuf;
263                 prbuf->expected_seqno = prbuf->first_seq = peer_initial_seqno;
264                 prbuf->q_size = rcvbuf_size;;
265                 prbuf->pkt_q = (struct rudp_pkt**)calloc(sizeof(void*), rcvbuf_size);
266                 prbuf->win = prbuf->q_size - 1;
267         }
268         pcb->cwnd = 2;
269         pcb->rtw_size = rawnd/2;//8;
270         pcb->rwin_size = rawnd;
271         pcb->ssthresh = rawnd;
272
273         pcb->srtt = 0;
274         pcb->sdev = 3;
275         pcb->rto = 6;   //As [Jacobson 1988] rto = srtt + 2*sdev, but it seems too large for us
276
277         return pcb;
278 }
279
280 static void _terminateSocketInternally(struct rudp_socket *s, int err)
281 {
282         if(s->state == RS_DEAD) return;
283
284         PA_MutexLock(s->mutex_r);
285         PA_MutexLock(s->mutex_w);
286
287         s->state = RS_DEAD;
288         s->err = err;
289
290         if(s->pcb)
291         {
292                 int i;
293                 for(i=0; i<MAX_PHY_CHANNELS; i++)
294                 {
295                         struct rudp_pkt *c;
296                         struct rcvbuf *prb;
297
298                         c = s->pcb->channel[i].sbuf.first;
299                         while(c)
300                         {
301                                 struct rudp_pkt *p = c;
302                                 c = c->next;
303                                 _MBufPutPacket(p);
304                         }
305
306                         prb = &s->pcb->channel[i].rbuf;
307                         for(; prb->head != prb->tail; prb->head = (prb->head+1)%prb->q_size)
308                                 if(prb->pkt_q[prb->head])
309                                         _MBufPutPacket(prb->pkt_q[prb->head]);
310                         free(prb->pkt_q);
311                 }
312                 free(s->pcb);
313                 s->pcb = NULL;
314         }
315
316         SETEVENT(s->event_r);
317         SETEVENT(s->event_w);
318
319         PA_MutexUnlock(s->mutex_w);
320         PA_MutexUnlock(s->mutex_r);
321
322 #if 0
323         //Still in listening queue
324         if(list_empty(&s->inst_list) && !list_empty(&s->listen_queue))
325         {
326                 list_del(&s->listen_queue);
327                 free(s);
328         }
329 #endif
330         //dbg_msg("################## _terminateSocketInternally ##########\n");
331 }
332
333 /// \brief Should be called with "mutex_sock_list" hold
334 //  \param err error code for the reason to cleanup this socket
335 static void _CleanupSocket(struct rudp_socket *s, int err)
336 {
337         if(s->state == RS_DEAD) return;
338
339         _terminateSocketInternally(s, err);
340
341         PA_MutexUninit(s->mutex_r);
342         PA_MutexUninit(s->mutex_w);
343 #if defined(_WIN32) || defined(ARM_UCOS_LWIP)
344         PA_EventUninit(s->event_r);
345         PA_EventUninit(s->event_w);
346 #else
347         pthread_cond_destroy(&s->event_r);
348         pthread_cond_destroy(&s->event_w);
349 #endif
350
351         if(!list_empty(&s->listen_queue))
352         {
353                 struct list_head *pp, *qq;
354                 list_for_each_safe(pp, qq, &s->listen_queue)
355                 {
356                         struct rudp_socket *sl = list_entry(pp, struct rudp_socket, listen_queue);
357                         _CleanupSocket(sl, 0);
358                         list_del(pp);
359                         free(sl);
360                 }
361         }
362
363         s->state = RS_DEAD;
364         //s->tag = 0;
365 }
366
367 static void _CleanAndFreeSocket(struct rudp_socket *s)
368 {
369         if(list_empty(&s->inst_list)) //accepted
370         {
371                 list_del(&s->accepted_list);
372         }
373         else 
374         {
375                 list_del(&s->inst_list);
376                 if(list_empty(&s->accepted_list))
377                         PA_SocketClose(s->udp_sock);
378                 else
379                 {
380                         struct rudp_socket *aa = list_entry(s->accepted_list.next, struct rudp_socket, accepted_list);
381                         INIT_LIST_HEAD(&aa->inst_list);
382                         list_add_tail(&aa->inst_list, &sock_list);
383                 }
384         }
385
386         if(s->state != RS_DEAD) _CleanupSocket(s, 0);
387
388         free(s);
389 }
390
391 void _timerProc(TimerHandler handler)
392 {
393         struct list_head *p, *q, *pp, *qq;
394         //PA_MutexLock(mutex_sock_list);
395         list_for_each_safe(p, q, &sock_list)
396         {
397                 struct rudp_socket *s, *ss;
398                 s = list_entry(p, struct rudp_socket, inst_list);
399
400                 if(s->state == RS_DEAD) continue;
401
402                 list_for_each_safe(pp, qq, &s->accepted_list)
403                 {
404                         ss = list_entry(pp, struct rudp_socket, accepted_list);
405                         handler(ss);
406                 }
407                 list_for_each_safe(pp, qq, &s->listen_queue)    //a socket in listen_queue may be removed due to timeout
408                 {
409                         ss = list_entry(pp, struct rudp_socket, listen_queue);
410                         handler(ss);
411                 }
412
413                 handler(s);
414         }
415         //PA_MutexUnlock(mutex_sock_list);
416 }
417
418 static void _congestionAvoidance(struct rudp_socket *s)
419 {
420         if(s->pcb->cwnd < s->pcb->ssthresh)
421         {//slow start 
422                 s->pcb->cwnd++;
423 #if 1
424                 s->pcb->ca_cnt++;
425                 if(s->pcb->ca_cnt >= s->pcb->rwin_size)
426 #endif
427                 if(s->pcb->rtw_size < s->pcb->rwin_size)
428                         s->pcb->rtw_size++;
429         }
430         else
431         {//congestion avoidance, increase cwnd slowly
432                 s->pcb->ca_cnt++;
433                 if(s->pcb->ca_cnt >= s->pcb->cwnd)
434                 {
435                         s->pcb->ca_cnt = 0;
436                         if(s->pcb->cwnd < s->pcb->rwin_size)
437                         {
438                                 s->pcb->cwnd++;
439                                 //s->pcb->ssthresh++; ???
440                         }
441                         if(s->pcb->rtw_size < s->pcb->rwin_size)
442                                 s->pcb->rtw_size++;
443                 }
444         }
445 }
446
447 static void _congestionDetected(struct rudp_socket *s, int chno, int what)
448 {
449         //int rawnd, i;
450         struct rudp_pcb *pcb;
451
452         //for(i=rawnd=0; i<MAX_CHANNELS; i++) rawnd += pcb->channel[chno].sbuf.rawnd;
453
454         pcb = s->pcb;
455         pcb->ssthresh = min(pcb->channel[chno].sbuf.rawnd, pcb->cwnd)/2;
456         if(pcb->ssthresh < 2) pcb->ssthresh = 2;
457
458         if(what == CONGESTED) pcb->cwnd = 1; 
459         else pcb->cwnd = pcb->ssthresh + 3;
460
461         switch(what)
462         {
463         case CONGESTED:
464         case FASTRETRANS2:
465                 pcb->rtw_size >>= 1; 
466                 if(pcb->rtw_size < 8) pcb->rtw_size = 8; 
467                 break;
468
469         case FASTRETRANS:
470                 pcb->rtw_size -= pcb->rtw_size >> 2;
471                 if(pcb->rtw_size < 8) pcb->rtw_size = 8;
472                 break;
473         }
474 }
475
476 static INLINE unsigned int _calcCurWnd(struct rudp_socket *s, struct sndbuf *psbuf)
477 {
478         //if receiver's rawnd is 0, still send one more packet then transmission can be
479         //started again by re-transfer timer, even when the receiver's OPENWND ACK(s) are lost
480         return min(s->pcb->cwnd, psbuf->rwnd); 
481
482         //return min(min(s->pcb->cwnd, psbuf->rwnd),psbuf->rawnd);
483         //return psbuf->rwnd;
484 }
485
486 /** Output a packet
487  *
488  *  mutex_w shall be hold before call _RudpOutput
489  *
490  *  return: 1 - if a packet is sent; otherwise, no packet is sent
491  */
492 static int _RudpOutput(struct rudp_socket *s, int chno, int opt)
493 {
494         struct sndbuf *psbuf;
495         struct rcvbuf *prbuf;
496         struct rudp_channel *pch;
497
498         if(s->tag != RUDP_SOCKET_TAG) return -1;
499         if(s->state <= RS_CLOSED) return -1;
500
501         pch = &s->pcb->channel[chno];
502         psbuf = &pch->sbuf;
503         prbuf = &pch->rbuf;
504
505         //if(pch->congested && opt == RO_NORMAL) return;
506         if(opt == RO_REXMT || opt == RO_REXMT_FAST)     //packets are queued before
507         {
508                 struct rudp_pkt *pkt = opt == RO_REXMT_FAST ? psbuf->rexmt : psbuf->first;
509                 if(!pkt) return 0;
510                 if(prbuf->should_ack == ACKT_DELAYED)
511                 {
512                         prbuf->should_ack = 0;
513                         pkt->hdr.flags.ack = 1;
514                         pkt->hdr.ackno = ntohl(prbuf->expected_seqno);
515                         pkt->hdr.flags.n_loss = prbuf->n_lost;
516                         //if(psbuf->first->trans)       psbuf->first->hdr.crc32 = calc_crc32(0, (char*)&psbuf->first->hdr, offsetof(struct rudp_hdr, crc32));
517                 }
518                 _sendPacket(s, pch, pkt, opt);
519                 pkt->hdr.flags.ack = 0;
520                 return 1;
521         }
522         
523         if(((prbuf->should_ack == ACKT_DELAYED) && !psbuf->first) || prbuf->should_ack == ACKT_OPENWND)
524         {
525                 _sendAck(s, chno);
526                 prbuf->should_ack = 0;
527
528                 return 0;
529         }
530
531         if(opt == 0 && pch->sbuf.rawnd == 0)
532         {
533                 if(pch->timer[RCT_REXMT] == 0)
534                         pch->timer[RCT_PERSIST] = s->pcb->rto * rudp_backoff[pch->sbuf.first?pch->sbuf.first->trans:0];
535                 //signalOutput(s, chno);
536         }
537         else
538         {
539                 struct rudp_pkt *p;
540
541                 p = psbuf->not_sent;
542                 pch->timer[RCT_PERSIST] = 0;
543                 if(p && (opt == RO_FORCE /*|| prbuf->should_ack == ACKT_DELAYED */
544                                         || _calcCurWnd(s, psbuf) > psbuf->n_unacked
545                                                 /* && psbuf->n_unacked < s->pcb->rtw_size*/))
546                         //psbuf->n_unacked < psbuf->rawnd) )
547                 {
548                         if(prbuf->should_ack == ACKT_DELAYED)
549                         {
550                                 prbuf->should_ack = 0;
551                                 p->hdr.flags.ack = 1;
552                                 p->hdr.ackno = ntohl(prbuf->expected_seqno);
553                                 p->hdr.flags.n_loss = prbuf->n_lost;
554                                 //if(p->trans) p->hdr.crc32 = calc_crc32(0, (char*)&p->hdr, offsetof(struct rudp_hdr, crc32));
555                         }
556                         //psbuf->n_unacked++;
557                         _sendPacket(s, pch, p, opt);
558                         p->hdr.flags.ack = 0;
559                         p = p->next;
560                         //psbuf->not_sent = p = p->next;
561                         if(p && p->seqno < psbuf->not_sent->seqno)
562                         {
563                                 dbg_msg("#####################################################\n");
564                         }
565                         psbuf->not_sent = p;
566
567                         //if(psbuf->rwnd > 0) 
568                         psbuf->rwnd--;
569                         return 1;
570                         if(opt == RO_ONLYONE) return 1;
571
572                         if(_calcCurWnd(s, psbuf) && p)
573                         {
574                                 //signalOutput(s, chno);
575                                 //struct output_notify notify = { s, chno };
576                                 //PA_Send(sockw_s, &notify, sizeof(notify), 0);
577                         }
578                 }
579         }
580
581         return 0;
582 }
583
584 void _handleTimer500ms(struct rudp_socket *s)
585 {
586         int i, j;
587         struct rudp_pcb *pcb;
588
589         if(s->state == RS_LISTEN || s->state == RS_DEAD) return;
590         pcb = s->pcb;
591         if(pcb)
592         {
593                 int sbuf_is_empty = 1;
594                 //rudp_now ++;
595
596                 PA_MutexLock(s->mutex_w);
597                 for(i=0; i<MAX_PHY_CHANNELS; i++)
598                 {
599                         struct rudp_channel *pch = &pcb->channel[i];
600                         if(pch->sbuf.first) sbuf_is_empty = 0;
601                         for(j=0; j<RCT_CNT; j++)
602                         {
603                                 if(pch->timer[j] == 0) continue;
604                                 pch->timer[j] --;
605                                 if(pch->timer[j] == 0)
606                                 {
607                                         switch(j)
608                                         {
609                                         case RCT_PERSIST:
610                                                 dbg_msg("Persist timeout.\n");
611                                                 _RudpOutput(s, i, RO_FORCE);
612                                                 break;
613                                         case RCT_REXMT:
614                                                 if(pch->sbuf.first)
615                                                 {
616                                                         if(pch->sbuf.first->trans >= MAX_REXMT_ATTEMPT)
617                                                         {
618                                                                 PA_MutexUnlock(s->mutex_w);
619                                                                 _CleanupSocket(s, ERUDP_TIMEOUTED);
620                                                                 s->state = RS_DEAD;
621                                                                 s->err = ERUDP_TIMEOUTED;
622                                                                 return;
623                                                         }
624                                                         else if(pch->sbuf.first->trans)
625                                                         {
626                                                                 _congestionDetected(s, i, CONGESTED);
627                                                                 _printTime(); dbg_msg("congested: cwnd=%d, ssthresh=%d\n", pcb->cwnd, pcb->ssthresh);
628                                                                 _congestionAvoidance(s);
629                                                                 _RudpOutput(s, i, RO_REXMT);
630                                                                 pch->congested = 1;
631                                                                 pch->sbuf.pkt_rttm_start = pch->sbuf.not_sent;
632                                                         }
633                                                         else
634                                                                 _RudpOutput(s, i, 0);
635                                                 }
636                                                 break;
637                                         }
638                                 }
639                         }
640                 }
641                 if(sbuf_is_empty && s->state == RS_FIN_QUEUED)
642                 {
643                         _sendFin(s);
644                         s->state = RS_FIN_WAIT_1;
645                         s->timer[RT_KEEP] = RTT_MIN * RTV_KEEP_CLOSE;
646                 }
647                 PA_MutexUnlock(s->mutex_w);
648         }
649
650         for(i=0; i<RT_CNT; i++)
651         {
652                 if(s->timer[i] == 0) continue;
653
654                 s->timer[i]--;
655                 if(s->timer[i] == 0)
656                 {
657                         switch(i)
658                         {
659                         case RT_KEEP:   //for connecting timeout
660                                 if(s->state == RS_SYN_RCVD || s->state == RS_SYN_SENT)
661                                 {
662                                         if(s->pcb->retr_cnt >= MAX_RECONN_ATTEMPT)
663                                         {
664                                                 if(list_empty(&s->inst_list))
665                                                 {
666                                                         list_del(&s->listen_queue);
667                                                         INIT_LIST_HEAD(&s->listen_queue);
668                                                         _CleanupSocket(s, ERUDP_TIMEOUTED);
669                                                         free(s);
670                                                 }
671                                                 else
672                                                 {
673                                                         //_CleanupSocket(s, ERUDP_TIMEOUTED);
674                                                         s->err = ERUDP_TIMEOUTED;
675                                                         s->state = RS_CLOSED;
676                                                         SETEVENT(s->event_w);
677                                                 }
678                                                 return;
679                                         }
680                                         else
681                                         {
682                                                 s->timer[RT_KEEP] = conn_backoff[++s->pcb->retr_cnt];
683                                                 if(s->state == RS_SYN_SENT)
684                                                         _sendSyn(s);
685                                                 else
686                                                         _sendSynAck(s);
687                                         }
688                                 }
689                                 else if(s->state >= RS_FIN_QUEUED)
690                                 {
691                                         dbg_msg("clean and free %p\n", s);
692                                         _CleanAndFreeSocket(s);
693                                 }
694                                 break;
695                         case RT_2MSL:
696                                 break;
697                         }
698                 }
699         }
700 }
701
702 void _handleTimer200ms(struct rudp_socket *s)
703 {
704         if(s->pcb)// && (s->pcb->r_flags & RUDPF_DELAYACK))
705         {
706                 int i;
707                 for(i=0; i<MAX_PHY_CHANNELS; i++)
708                 {
709                         struct rcvbuf *prb = &s->pcb->channel[i].rbuf;
710                         if(prb->should_ack)
711                         {
712                                 //_printTime(); dbg_msg("delayed ack.\n");
713                                 PA_MutexLock(s->mutex_w);
714                                 _RudpOutput(s, i, 0);
715                                 //signalOutput(s, i);
716                                 PA_MutexUnlock(s->mutex_w);
717                         }
718                 }
719         }
720 }
721 void _sendHeader(struct rudp_socket *s, struct rudp_hdr *phdr)
722 {
723         _printHdr(s->pcb, phdr, &s->pcb->peer);
724         phdr->crc32 = calc_crc32(0, (char*)phdr, offsetof(struct rudp_hdr, crc32));
725         PA_SendTo(s->udp_sock, phdr, sizeof(struct rudp_hdr), 0, 
726                         s->connected?NULL:(struct sockaddr*)&s->pcb->peer, 
727                         sizeof(struct sockaddr));
728 }
729
730 void _sendPacket(struct rudp_socket *s, struct rudp_channel *pch, struct rudp_pkt *pkt, int opt)
731 {
732         if(pch->timer[RCT_REXMT] == 0)
733                 pch->timer[RCT_REXMT] = s->pcb->rto * rudp_backoff[pkt->trans];
734         pkt->ts = rudp_now;
735         //dbg_msg("............. seq %u, ts %d...........", pkt->seqno, rudp_now);
736         pkt->hdr.flags.window = WINDOW_HTON(pch->rbuf.win);
737         if(opt != RO_REXMT_FAST)
738         {
739                 if(!pkt->trans) pch->sbuf.n_unacked++;
740                 pkt->trans ++; 
741                 if(pkt->trans >= MAX_REXMT_ATTEMPT) pkt->trans = MAX_REXMT_ATTEMPT;
742         }
743         pkt->hdr.crc32 = calc_crc32(0, (char*)&pkt->hdr, offsetof(struct rudp_hdr, crc32));
744
745         _printPkt(s->pcb, pkt, PHF_DATA|pch->sbuf.rwnd, &s->pcb->peer);
746         PA_SendTo(s->udp_sock, &pkt->hdr, sizeof(struct rudp_hdr) + pkt->len, 0, 
747                         s->connected?NULL:(struct sockaddr*)&s->pcb->peer, 
748                         sizeof(struct sockaddr));
749 }
750 void _sendSyn(struct rudp_socket *s)
751 {
752         struct rudp_hdr hdr;
753         hdr.u32_flags = 0;
754         hdr.flags.rudp = RUDP_HEADER_TAG;
755         hdr.flags.syn = 1;
756         hdr.seqno = htonl(s->pcb->channel[0].sbuf.seqno);
757         hdr.ackno = 0;
758         hdr.flags.window = WINDOW_HTON(s->pcb->channel[0].rbuf.win);
759         _sendHeader(s, &hdr);
760 }
761 void _sendSynAck(struct rudp_socket *s)
762 {
763         struct rudp_hdr hdr;
764         hdr.u32_flags = 0;
765         hdr.flags.rudp = RUDP_HEADER_TAG;
766         hdr.flags.syn = 1;
767         hdr.seqno = htonl(s->pcb->channel[0].sbuf.seqno);
768         hdr.flags.ack = 1;
769         hdr.ackno = htonl(s->pcb->channel[0].rbuf.expected_seqno);
770         hdr.flags.window = WINDOW_HTON(s->pcb->channel[0].rbuf.win);
771         _sendHeader(s, &hdr);
772 }
773 //only ack flag
774 void _sendEmptyAck(struct rudp_socket *s, int chno)
775 {
776         struct rudp_hdr hdr;
777         hdr.u32_flags = 0;
778         hdr.flags.rudp = RUDP_HEADER_TAG;
779         hdr.seqno = 0;
780         hdr.flags.chno = chno;
781         hdr.flags.ack = 1;
782         hdr.ackno = 0;
783         hdr.flags.window = 0;
784         _sendHeader(s, &hdr);
785 }
786
787 //ack without data
788 void _sendAck(struct rudp_socket *s, int chno)
789 {
790         struct rudp_hdr hdr;
791         struct rcvbuf *pr = &s->pcb->channel[chno].rbuf;
792
793         hdr.u32_flags = 0;
794         hdr.flags.rudp = RUDP_HEADER_TAG;
795         hdr.flags.ack = 1;
796         hdr.flags.chno = chno;
797         hdr.seqno = htonl(s->pcb->channel[chno].sbuf.seqno);
798         hdr.ackno = htonl(pr->expected_seqno);
799         hdr.flags.n_loss = pr->n_lost;
800         hdr.flags.window = WINDOW_HTON(pr->win);
801         _sendHeader(s, &hdr);
802
803         pr->acked_seqno = pr->expected_seqno;
804         pr->should_ack = 0;
805 }
806 void _sendFin(struct rudp_socket *s)
807 {
808         struct rudp_hdr hdr;
809         hdr.u32_flags = 0;
810         hdr.flags.rudp = RUDP_HEADER_TAG;
811         hdr.flags.fin = 1;
812         hdr.seqno = 0;
813         hdr.ackno = 0;
814         hdr.flags.window = 0;
815         _sendHeader(s, &hdr);
816 }
817
818
819 void _updateRTO(struct rudp_socket *s, int rtt)
820 {
821         int rto0 = s->pcb->rto;
822 #if 0
823         /* [Jacobson 1988],  refresh rto */
824         int drtt = rtt - s->pcb->srtt;
825         if(drtt > 0)
826         {
827                 s->pcb->srtt += drtt >> 3;
828                 if(drtt > s->pcb->sdev)
829                         s->pcb->sdev += (drtt - s->pcb->sdev) >> 2;
830                 else
831                         s->pcb->sdev -= (s->pcb->sdev - drtt) >> 2;
832         }
833         else
834         {
835                 drtt = -drtt;
836                 s->pcb->srtt -= drtt >> 3;
837                 if(drtt > s->pcb->sdev)
838                         s->pcb->sdev += (drtt - s->pcb->sdev) >> 2;
839                 else
840                         s->pcb->sdev -= (s->pcb->sdev - drtt) >> 2;
841         }
842         s->pcb->rto = s->pcb->srtt + (s->pcb->sdev > 0) ?(s->pcb->sdev << 2):(-s->pcb->sdev << 2);
843         if(s->pcb->rto < 2) s->pcb->rto = 2;
844         dbg_msg("rtt = %d, rto = %d\n", rtt, s->pcb->rto);
845 #else
846         if(rtt < RTT_MIN) rtt = RTT_MIN;
847         //if(rtt < 2) rtt = 2;
848         s->pcb->rto = rtt;
849 #endif
850         if(s->pcb->rto - rto0 > 0)
851         {
852                 s->pcb->cwnd -= s->pcb->cwnd >> 2;
853                 //s->pcb->rtw_size -= s->pcb->rtw_size >> 2;
854         }
855 }
856
857 INLINE BOOL _isPacketValid(struct rudp_pkt *pkt)
858 {
859
860 }
861
862 int _DispatchPacket(struct rudp_socket *s, struct rudp_pkt *pkt, const struct sockaddr *from, int from_len)
863 {
864         struct list_head *pp, *qq;
865         struct rudp_socket *sa;
866         struct sockaddr_in *sp, *sf;
867
868         sf = (struct sockaddr_in*)from;
869
870         /* We must search each queue to make sure there is no duplicated connection for a listening socket */
871
872         if(s->state == RS_LISTEN)
873         {
874                 list_for_each_safe(pp, qq, &s->listen_queue)
875                 {
876                         sa = list_entry(pp, struct rudp_socket, listen_queue);
877                         if(!sa->pcb) continue;
878                         sp = (struct sockaddr_in*)&sa->pcb->peer;
879                         if(sp->sin_addr.s_addr == sf->sin_addr.s_addr && sp->sin_port == sf->sin_port)
880                         {
881                                 int check_again;
882                                 if(pkt->hdr.flags.rst)
883                                 {
884                                         list_del(&sa->listen_queue);
885                                         INIT_LIST_HEAD(&sa->listen_queue);
886                                         _CleanupSocket(sa, ERUDP_RESETED);
887                                         free(sa);
888                                         return 0;
889                                 }
890
891                                 check_again = 0;
892                                 if(pkt->hdr.flags.ack && sa->state == RS_SYN_RCVD)
893                                         check_again = 1;
894                                 if(_ProcessPacket(sa, pkt, from, from_len) < 0)
895                                         _MBufPutPacket(pkt);
896                                 if(check_again && sa->state == RS_ESTABLISHED)
897                                         SETEVENT(s->event_r);
898                                 return 0;
899                         }
900                 }
901         }
902
903         list_for_each(pp, &s->accepted_list)
904         {
905                 sa = list_entry(pp, struct rudp_socket, accepted_list);
906                 if(sa->state >= RS_ESTABLISHED)
907                 {
908                         sp = (struct sockaddr_in*)&sa->pcb->peer;
909                         if(sp->sin_addr.s_addr == sf->sin_addr.s_addr && sp->sin_port == sf->sin_port)
910                         {
911                                 if(_ProcessPacket(sa, pkt, from, from_len) < 0)
912                                         _MBufPutPacket(pkt);
913                                 return 0;
914                         }
915                 }
916         }
917
918         /* It's time to Me */
919         if(s->state == RS_LISTEN/*listening socket*/ ||
920                         ( s->pcb && (s->connected/*client*/
921                                         || (((sp = (struct sockaddr_in*)&s->pcb->peer), sp->sin_addr.s_addr == sf->sin_addr.s_addr)
922                                                 && (sp->sin_port == sf->sin_port)/*accepted(listening socket is closed)*/) )
923                                   )
924           )
925         {
926                 if(_ProcessPacket(s, pkt, from, from_len) < 0)
927                         _MBufPutPacket(pkt);
928                 return 0;
929         }
930
931         /* Nobody want this packet */
932         if(!(pkt->hdr.flags.rst && s->state <= 0)) 
933                 _sendReset(s, from);
934         _MBufPutPacket(pkt);
935         return 0;
936 }
937
938 static int _PPState_Established(struct rudp_socket *s, struct rudp_pkt *pkt, const struct sockaddr *from, int from_len)
939 {
940         struct rudp_channel *pch;
941         struct sndbuf *psbuf;
942         struct rcvbuf *prbuf;
943         int old_rawnd;
944         int chno;
945
946         if(pkt->hdr.flags.syn) 
947         { 
948                 if(pkt->hdr.flags.ack)
949                         _sendAck(s, 0);
950                 else
951                         _sendReset(s, from); 
952                 return -1; 
953         }
954         if(pkt->hdr.flags.fin)
955         {
956                 int i, ii;
957                 PA_MutexLock(s->mutex_w);
958                 s->state = RS_CLOSE_WAIT;
959                 _sendAck(s, 0);
960                 s->timer[RT_KEEP] = RTT_MIN * RTV_KEEP_CLOSE;
961
962                 //
963                 // Cleanup sndbuf
964                 //
965                 for(i=0; i<MAX_PHY_CHANNELS; i++)
966                 {
967                         struct sndbuf *psb = &s->pcb->channel[i].sbuf;
968                         struct rudp_pkt *c = psb->first;
969                         while(c)
970                         {
971                                 struct rudp_pkt *p = c;
972                                 c = c->next;
973                                 _MBufPutPacket(p);
974                         }
975                         memset(psb, 0, sizeof(struct sndbuf));
976                         for(ii=0; ii<RCT_CNT; ii++) s->pcb->channel[i].timer[ii] = 0;
977                 }
978                 for(i=0; i<RT_CNT; i++) s->timer[i] = 0;
979
980                 PA_MutexUnlock(s->mutex_w);
981                 goto _checkdata;
982         }
983
984         chno = pkt->hdr.flags.chno;
985         pch = &s->pcb->channel[chno];
986         psbuf = &pch->sbuf;
987         old_rawnd = psbuf->rawnd;
988         psbuf->rawnd = WINDOW_NTOH(pkt->hdr.flags.window);
989         //psbuf->rwnd += old_rawnd - psbuf->rawnd;
990         psbuf->rwnd = psbuf->rawnd - psbuf->n_unacked;
991         if(psbuf->rwnd < 0) psbuf->rwnd = 0;
992
993
994         if(pkt->hdr.flags.ack && psbuf->first)
995         {
996                 uint32_t ackno = ntohl(pkt->hdr.ackno);
997
998                 PA_MutexLock(s->mutex_w);
999                 if(SEQ_LE(ackno, psbuf->first->seqno)/* && !pch->congested*/)   //duplicated ACK
1000                 //if(ackno == psbuf->first->seqno) //duplicated ACK
1001                 {
1002                         if(old_rawnd == 0 && psbuf->rawnd > 0)  //Recevier's window opened
1003                         {
1004                                 _RudpOutput(s, pkt->hdr.flags.chno, RO_FORCE);
1005                                 PA_MutexUnlock(s->mutex_w);
1006                                 goto _checkdata;
1007                         }
1008
1009                         psbuf->dup_ack++;
1010                         if(psbuf->dup_ack >= 3)
1011                         {
1012                                 if(psbuf->dup_ack == 3)
1013                                 {
1014                                         psbuf->rlost = pkt->hdr.flags.n_loss;
1015                                         if(psbuf->rlost == 0) psbuf->rlost = 1;
1016                                         psbuf->rexmt = psbuf->first;
1017                                         _congestionDetected(s, chno, psbuf->rlost>1?FASTRETRANS2:FASTRETRANS);
1018                                         _printTime(); dbg_msg("duplicated ACKs(%d): rlost=%d, cwnd=%d, ssthresh=%d\n", 
1019                                                         ackno, psbuf->rlost, s->pcb->cwnd, s->pcb->ssthresh);
1020
1021                                         pch->timer[RCT_REXMT] = s->pcb->rto * rudp_backoff[0] + 1;
1022
1023                                         psbuf->pkt_rttm_start = psbuf->not_sent;
1024                                         psbuf->fastretr_end_seq = psbuf->first->seqno + psbuf->n_unacked - 1;
1025                                 }
1026
1027                                 if(psbuf->rlost && psbuf->rexmt)
1028                                 {
1029                                         _RudpOutput(s, pkt->hdr.flags.chno, RO_REXMT_FAST);
1030                                         psbuf->rexmt = psbuf->rexmt->next;
1031                                         psbuf->rlost --; //if(psbuf->rlsot == 0) psbuf->rexmt = NULL;
1032                                 }
1033                                 else if(psbuf->dup_ack > 3)
1034                                 {
1035                                         s->pcb->cwnd ++;
1036                                         // Send one new packet every two duplicated acks.
1037                                         // Because each ack means a packet(very possible being valid) is received by peer,
1038                                         // so we can inject new packet into network
1039                                         if(psbuf->dup_ack & 1) _RudpOutput(s, pkt->hdr.flags.chno, RO_FORCE);
1040
1041                                         if(s->pcb->cwnd > s->pcb->ssthresh)
1042                                                 s->pcb->cwnd = s->pcb->ssthresh;
1043                                         //psbuf->dup_ack = 0;
1044                                 }
1045                         }
1046                         else
1047                                 _RudpOutput(s, pkt->hdr.flags.chno, RO_ONLYONE);
1048                 }
1049                 else// if(SEQ_GT(ackno, psbuf->first->seqno))
1050                 {
1051                         struct rudp_pkt *p, *p2;
1052                         int fast_rxmt_end = 0;  //fast retransmission
1053
1054                         p = psbuf->first;
1055                         //while(p && p->seqno != ackno && psbuf->n_unacked)
1056                         while(p && p->seqno < ackno)
1057                         {//remove acked packets
1058                                 if(psbuf->pkt_rttm_start == p)
1059                                         psbuf->pkt_rttm_start = NULL;
1060                                 if(p->trans == 1 && psbuf->pkt_rttm_start == NULL)
1061                                         _updateRTO(s, rudp_now - p->ts);
1062
1063                                 if(p->seqno == psbuf->fastretr_end_seq && psbuf->dup_ack >= 3)
1064                                         fast_rxmt_end = 1;
1065                                 p2 = p;
1066                                 p = p->next;
1067                                 _MBufPutPacket(p2);
1068                                 psbuf->n_unacked --;
1069                                 assert(psbuf->n_unacked>=0);
1070                                 psbuf->n_pkt --;
1071                                 psbuf->rwnd ++;
1072
1073                                 // Slow start && congestion avoidance
1074                                 _congestionAvoidance(s);
1075
1076                                 // If recovery from congestion, or, after a fast retransmission,
1077                                 // there's another hole in the unacked queue, continue performing
1078                                 // fast retransmission.
1079                                 // Otherwise, stop fast recovery
1080                                 if(psbuf->rlost && psbuf->rexmt)
1081                                 {
1082                                         _RudpOutput(s, pkt->hdr.flags.chno, RO_REXMT_FAST);
1083                                         psbuf->rexmt = psbuf->rexmt->next;
1084                                         psbuf->rlost --; //if(psbuf->rlsot == 0) psbuf->rexmt = NULL;
1085                                 }
1086                                 else if(pch->congested)
1087                                 {
1088                                         psbuf->dup_ack ++;
1089                                         if(psbuf->dup_ack & 1) _RudpOutput(s, pkt->hdr.flags.chno, RO_FORCE);
1090
1091                                         if(s->pcb->cwnd > s->pcb->ssthresh)
1092                                         {
1093                                                 s->pcb->cwnd = s->pcb->ssthresh;
1094                                                 pch->congested = 0;
1095                                         }
1096                                 }
1097                                 else
1098                                 {
1099                                         psbuf->dup_ack = 0;
1100                                         if(old_rawnd == 0 && psbuf->rawnd > 0)  //Recevier's window opened
1101                                                 _RudpOutput(s, pkt->hdr.flags.chno, RO_FORCE);
1102                                         else
1103                                                 while(_RudpOutput(s, pkt->hdr.flags.chno, 0));
1104                                 }
1105                         }
1106                         psbuf->first = p;
1107
1108                         if(!p)
1109                         {
1110                                 psbuf->pkt_rttm_start = psbuf->not_sent = psbuf->last = NULL;   //enable rtt measurement
1111                                 pch->timer[RCT_REXMT] = 0;
1112
1113                                 assert(psbuf->n_pkt==0);
1114                         }
1115                         else
1116                                 pch->timer[RCT_REXMT] = s->pcb->rto * rudp_backoff[pkt->trans];
1117
1118                         //signalOutput(s, pkt->hdr.flags.chno);
1119                         SETEVENT(s->event_w);
1120                 }
1121                 PA_MutexUnlock(s->mutex_w);
1122         }
1123
1124 _checkdata:
1125         if(pkt->len)    //length of data > 0
1126         {
1127                 uint32_t pos, seqno;
1128                 int delta;
1129
1130                 PA_MutexLock(s->mutex_r);
1131                 seqno = ntohl(pkt->hdr.seqno);
1132                 prbuf = &pch->rbuf;
1133
1134                 delta = (int)(seqno - prbuf->first_seq);
1135                 if(delta < 0) //old packet, just ignore it
1136                 { 
1137                         //PA_MutexUnlock(s->mutex_r);
1138                         dbg_msg("packet %d is ignored, expected_seqno=%d\n", pkt->seqno, prbuf->expected_seqno);
1139                         goto _sendack_and_discard_pkt;
1140                 }
1141                 if(delta < prbuf->q_size-1) //in the buffer
1142                 {
1143                         pos = (prbuf->head + delta)%prbuf->q_size;
1144                         if(prbuf->pkt_q[pos])   //duplicated
1145                         {
1146                                 dbg_msg("packet %d is duplicated.\n", pkt->seqno);
1147                                 goto _sendack_and_discard_pkt;
1148                         }
1149
1150                         prbuf->pkt_q[pos] = pkt;
1151
1152                         //update pointers & window
1153                         if((prbuf->tail + prbuf->q_size - prbuf->head)%prbuf->q_size <= 
1154                                         (pos + prbuf->q_size - prbuf->head)%prbuf->q_size)
1155                                 prbuf->tail = (pos+1)%prbuf->q_size;
1156                         prbuf->win = (prbuf->q_size + prbuf->head - prbuf->tail - 1)%prbuf->q_size;
1157
1158                         if(prbuf->loss == pos)  //just the one we expected
1159                         {
1160                                 //move "loss" to next empty slot, if any
1161                                 while(prbuf->loss != prbuf->tail && prbuf->pkt_q[prbuf->loss])
1162                                 {
1163                                         prbuf->loss = (prbuf->loss + 1) % prbuf->q_size;
1164                                         prbuf->expected_seqno++;
1165                                 }
1166                                 prbuf->should_ack = ACKT_DELAYED;
1167                                 SETEVENT(s->event_r);
1168                         }
1169
1170                         //(re-)calculate the size of (next, or current) hole.
1171                         {
1172                                 int loss = prbuf->loss, n_lost=0;
1173                                 while(loss != prbuf->tail && !prbuf->pkt_q[loss] && n_lost < MAX_LOSS_REPORT)
1174                                 {
1175                                         loss = (loss + 1) % prbuf->q_size;
1176                                         n_lost++;
1177                                 }
1178                                 prbuf->n_lost = n_lost;
1179                                 if(n_lost) prbuf->should_ack = 0;
1180                         }
1181
1182                         if(!prbuf->should_ack || 
1183                                         ((prbuf->should_ack == ACKT_DELAYED) && ((prbuf->expected_seqno - prbuf->acked_seqno) >= 3))
1184                                 )
1185                         {
1186                                 _sendAck(s, pkt->hdr.flags.chno);
1187                                 prbuf->should_ack = 0;
1188                         }
1189
1190                         PA_MutexUnlock(s->mutex_r);
1191                         return 0;
1192                 }
1193                 else
1194                         dbg_msg("exceeds receiver's buffer: %d\n", pkt->seqno);
1195 _sendack_and_discard_pkt:
1196                 PA_MutexUnlock(s->mutex_r);
1197                 _sendAck(s, pkt->hdr.flags.chno);
1198                 return -1;
1199         }
1200         else if(!pkt->hdr.flags.ack)    //What's this? fin?
1201         {
1202                 if(s->state == RS_CLOSE_WAIT)
1203                 {
1204                         PA_MutexLock(s->mutex_r);
1205                         s->err = ERUDP_PEER_CLOSED;
1206                         SETEVENT(s->event_r);
1207                         PA_MutexUnlock(s->mutex_r);
1208                 }
1209                 else
1210                 {
1211                         PA_MutexLock(s->mutex_w);
1212                         _RudpOutput(s, pkt->hdr.flags.chno, 0);
1213                         PA_MutexUnlock(s->mutex_w);
1214                 }
1215                 return -1;
1216         }
1217
1218         return -1;
1219 }
1220
1221
1222 /// \brief Process packet
1223 //  @return -1 -- if the packet will be released
1224 int _ProcessPacket(struct rudp_socket *s, struct rudp_pkt *pkt, const struct sockaddr *from, int from_len)
1225 {
1226         struct rudp_channel *pch;
1227         struct sndbuf *psbuf;
1228
1229         if((pkt->hdr.flags.rst) && s->state != RS_LISTEN)
1230         {
1231                 if(s->state == RS_SYN_SENT) 
1232                 {//To support simultanous connection, ignore it
1233                         //s->state = RS_CLOSED;
1234                         //s->err = ERUDP_RESETED;
1235                 }
1236                 else
1237                 {
1238                         _terminateSocketInternally(s, ERUDP_RESETED);
1239                         return -1;
1240                 }
1241         }
1242
1243         switch(s->state)
1244         {
1245                 case RS_CLOSED:
1246                         if(s->err) return -1;
1247                         if((s->flags & RF_ADHOC) && !s->pcb && pkt->hdr.flags.fin)
1248                         {
1249                                 return -1;
1250                         }
1251                         break;
1252
1253                 case RS_LISTEN:
1254                         if(pkt->hdr.flags.syn && !pkt->hdr.flags.ack)
1255                         {
1256                                 struct rudp_socket *ss;
1257                                 int sa_len;
1258
1259                                 ss = _AllocRudpSocket();
1260                                 ss->rcvbuf_sz = s->rcvbuf_sz;
1261                                 ss->udp_sock = s->udp_sock;
1262                                 ss->pcb = _AllocRudpPcb(ss->rcvbuf_sz, INITIAL_SEQ_NO, ntohl(pkt->hdr.seqno), WINDOW_NTOH(pkt->hdr.flags.window));
1263                                 memcpy(&ss->pcb->peer, from, from_len);
1264                                 sa_len = sizeof(struct sockaddr_in);
1265                                 PA_GetSockName(s->udp_sock, (struct sockaddr*)&ss->pcb->local, &sa_len);
1266
1267                                 ss->state = RS_SYN_RCVD;
1268                                 ss->timer[RT_KEEP] = conn_backoff[0];
1269                                 list_add_tail(&ss->listen_queue, &s->listen_queue);
1270
1271                                 _sendSynAck(ss);
1272
1273                                 return -1;
1274                         }
1275                         break;
1276
1277                 case RS_SYN_SENT:
1278                         if(pkt->hdr.flags.syn)
1279                         {
1280                                 int i;
1281                                 struct rudp_hdr hdr;
1282
1283                                 pch = &s->pcb->channel[0];
1284                                 psbuf = &pch->sbuf;
1285
1286                                 for(i=0; i<MAX_PHY_CHANNELS; i++)
1287                                 {
1288                                         pch[i].rbuf.expected_seqno = pch[i].rbuf.first_seq = ntohl(pkt->hdr.seqno);
1289                                         s->pcb->rwin_size = pch[i].sbuf.rwnd = pch[i].sbuf.rawnd = WINDOW_NTOH(pkt->hdr.flags.window);
1290                                         s->pcb->rtw_size = s->pcb->rwin_size/2;//8;
1291                                 }
1292                                 s->pcb->ssthresh = s->pcb->rwin_size; //s->pcb->rtw_size;
1293
1294                                 /* Send ACK for normal connection, finish handshake.
1295                                  *   or
1296                                  * Send SYN & ACK for simultaneous open.
1297                                  */
1298                                 memset(&hdr, 0, sizeof(hdr));
1299                                 hdr.u32_flags = 0;
1300                                 hdr.flags.rudp = RUDP_HEADER_TAG;
1301                                 hdr.flags.ack = 1;
1302                                 hdr.ackno = pkt->hdr.seqno;
1303                                 hdr.flags.window = WINDOW_HTON(s->pcb->channel[0].rbuf.win);
1304
1305                                 PA_MutexLock(s->mutex_w);
1306
1307                                 if(pkt->hdr.flags.ack)  //Normal open
1308                                 {
1309                                         _sendHeader(s, &hdr);
1310                                         s->state = RS_ESTABLISHED;
1311                                         SETEVENT(s->event_w);
1312                                 }
1313                                 else // Simultaneous open
1314                                 {
1315                                         //re-use packet
1316                                         hdr.flags.syn = 1;
1317                                         hdr.seqno = htonl(psbuf->seqno);
1318                                         _sendHeader(s, &hdr);
1319
1320                                         s->state = RS_SYN_RCVD;
1321                                 }
1322                                 PA_MutexUnlock(s->mutex_w);
1323                                 return -1;
1324                         }
1325                         break;
1326
1327                 case RS_SYN_RCVD:
1328                         if(pkt->hdr.flags.ack)// && pkt->hdr.ackno == s->pcb->channel[0].sbuf.seqno)
1329                         {
1330                                 pch = &s->pcb->channel[0];
1331                                 psbuf = &pch->sbuf;
1332
1333                                 /* Simultaneous open, wakeup thread wait on RUDPConnect(...) */
1334                                 if(list_empty(&s->listen_queue))
1335                                 {
1336                                         PA_MutexLock(s->mutex_w);
1337                                         s->state = RS_ESTABLISHED;
1338                                         SETEVENT(s->event_w);
1339                                         PA_MutexUnlock(s->mutex_w);
1340                                 }
1341                                 /* Accepted, wakeup thread wait on RUDPAccept(...) */
1342                                 else
1343                                 {
1344                                         //waiting thread is wakedup in _DispatchPacket...
1345                                         //since s is not returned by Accept yet, it's safe without lock
1346                                         s->state = RS_ESTABLISHED;
1347                                 }
1348                                 return -1;
1349                         }
1350                         else if(pkt->hdr.flags.syn)
1351                         {
1352                                 _sendSynAck(s);
1353                                 return -1;
1354                         }
1355                         break;
1356
1357                 case RS_ESTABLISHED:
1358                         return _PPState_Established(s, pkt, from, from_len);
1359
1360                 case RS_FIN_QUEUED:
1361                 case RS_FIN_WAIT_1:
1362                         if(pkt->hdr.flags.ack)
1363                         {
1364                                 if(pkt->hdr.flags.fin)
1365                                 {
1366                                         _sendEmptyAck(s, 0);
1367                                         s->state = RS_TIME_WAIT;
1368                                 }
1369                                 else
1370                                         s->state = RS_FIN_WAIT_2;
1371                         }
1372                         else if(pkt->hdr.flags.fin)
1373                         {
1374                                 _sendEmptyAck(s, 0);
1375                                 s->state = RS_CLOSING;
1376                         }
1377                         s->timer[RT_KEEP] = RTT_MIN * RTV_KEEP_CLOSE;
1378                         return -1;
1379
1380                 case RS_FIN_WAIT_2:
1381                         if(pkt->hdr.flags.fin)
1382                         {
1383                                 _sendAck(s, 0);
1384                                 s->state = RS_TIME_WAIT;
1385                         }
1386                         return -1;
1387
1388                 case RS_CLOSING:
1389                 case RS_TIME_WAIT:
1390                 case RS_CLOSE_WAIT:
1391                         break;
1392         }
1393         _sendReset(s, from);
1394         return -1;
1395 }
1396
1397 /* pcb might not be allocated, cann't replaced by _sendHeader */
1398 void _sendReset(struct rudp_socket *s, const struct sockaddr *to)
1399 {
1400         struct rudp_hdr hdr;
1401
1402         memset(&hdr, 0, sizeof(hdr));
1403         hdr.u32_flags = 0;
1404         hdr.flags.rudp = RUDP_HEADER_TAG;
1405         hdr.flags.rst = 1;
1406         hdr.crc32 = calc_crc32(0, (char*)&hdr, offsetof(struct rudp_hdr, crc32));
1407         _printHdr(s->pcb, &hdr, (struct sockaddr_in*)to);
1408         PA_SendTo(s->udp_sock, &hdr, sizeof(struct rudp_hdr), 0, 
1409                         s->connected?NULL:to,
1410                         sizeof(struct sockaddr));
1411 }
1412
1413 PA_THREAD_RETTYPE __STDCALL _RUDPServiceThread(void *pdata)
1414 {
1415         fd_set rfds;
1416         struct timeval tv;
1417         struct list_head *p;
1418         int max_fd;
1419         unsigned long t200, t500, tnow;
1420
1421         t200 = t500 = PA_GetTickCount();
1422         while(run)
1423         {
1424                 FD_ZERO(&rfds);
1425                 tv.tv_sec = 0; tv.tv_usec = 25*1000;
1426                 //FD_SET(sockw_r, &rfds);
1427                 //max_fd = sockw_r;
1428                 max_fd = -1;
1429
1430                 PA_MutexLock(mutex_sock_list);
1431                 list_for_each(p, &sock_list)
1432                 {
1433                         struct rudp_socket *s = list_entry(p, struct rudp_socket, inst_list);
1434                         //accepted socket's peer reseted ???
1435                         if(1)//s->state != RS_DEAD || !list_empty(&s->accepted_list))
1436                         {
1437                                 FD_SET(s->udp_sock, &rfds);
1438                                 max_fd = max(max_fd, s->udp_sock);
1439                         }
1440                 }
1441                 PA_MutexUnlock(mutex_sock_list);
1442
1443                 if(select(max_fd+1, &rfds, NULL, NULL, &tv) > 0)
1444                 {
1445                         PA_MutexLock(mutex_sock_list);
1446                         list_for_each(p, &sock_list)
1447                         {
1448                                 struct rudp_socket *s = list_entry(p, struct rudp_socket, inst_list);
1449                                 if(FD_ISSET(s->udp_sock, &rfds))
1450                                 {
1451                                         struct sockaddr from;
1452                                         int len, from_len;
1453                                         struct rudp_pkt *pkt;
1454
1455                                         while(1)
1456                                         {
1457                                                 pkt = _MBufGetPacket();
1458                                                 from_len = sizeof(from);
1459                                                 if(pkt)
1460                                                 {
1461                                                         len = PA_RecvFrom(s->udp_sock, &pkt->hdr, MAX_PACKET_SIZE, 0, &from, &from_len);
1462                                                         if(len < 0 || len < sizeof(struct rudp_hdr) || pkt->hdr.flags.rudp != RUDP_HEADER_TAG || !(
1463 #ifdef _DEBUG
1464                                                                         (calc_crc32(0, (char*)&pkt->hdr, offsetof(struct rudp_hdr, crc32)) == pkt->hdr.crc32)?TRUE:(printf("Invalid packet!\n"),FALSE)))
1465 #else
1466                                                                         calc_crc32(0, (char*)&pkt->hdr, offsetof(struct rudp_hdr, crc32)) == pkt->hdr.crc32))
1467 #endif
1468                                                         { 
1469                                                                 if(len < 0)
1470                                                                 {
1471 #ifdef _DEBUG
1472 #if defined(_WIN32)
1473                                                                         int err = WSAGetLastError();
1474                                                                         if(err != WSAEWOULDBLOCK)
1475                                                                                 dbg_msg("recvfrom error: %d\n", err);
1476 #elif defined(ARM_UCOS_LWIP)
1477                                                                         int err = lwip_get_error(s->udp_sock);
1478                                                                         if(err != EWOULDBLOCK)
1479                                                                                 dbg_msg("recvfrom: %s\n", lwip_strerr(err));
1480 #else
1481                                                                         if(errno != EWOULDBLOCK)
1482                                                                                 dbg_msg("recvfrom: %s\n", strerror(errno)); 
1483 #endif
1484 #endif
1485                                                                         //_terminateSocketInternally(s, ERUDP_RESETED); 
1486                                                                 }
1487                                                                 else if(s->non_rudp_pkt_cb)
1488                                                                         s->non_rudp_pkt_cb((const uint8_t*)&pkt->hdr, len, s->p_user);
1489                                                                 _MBufPutPacket(pkt);
1490                                                                 break;
1491                                                         }
1492
1493                                                         pkt->len = len - sizeof(struct rudp_hdr);
1494                                                         pkt->seqno = ntohl(pkt->hdr.seqno);
1495                                                         _printPkt(s->pcb, pkt, PHF_FROM, (struct sockaddr_in*)&from);
1496                                                         _DispatchPacket(s, pkt, &from, from_len);
1497                                                 }
1498                                                 else
1499                                                         break;
1500                                         }
1501                                 }
1502                         }
1503                         PA_MutexUnlock(mutex_sock_list);
1504                 }
1505
1506                 tnow = PA_GetTickCount();
1507                 PA_MutexLock(mutex_sock_list);
1508                 if(tnow - t200 >= DELAY_ACK_MS-4)
1509                 {
1510                         //t200 += DELAY_ACK_MS;
1511                         t200 = tnow;
1512                         _timerProc(_handleTimer200ms);
1513                 }
1514                 if(tnow - t500 >= RTT_UINT-4)
1515                 {
1516                         //t500 += RTT_UINT;
1517                         t500 = tnow;
1518                         rudp_now ++;
1519                         _timerProc(_handleTimer500ms);
1520                 }
1521                 PA_MutexUnlock(mutex_sock_list);
1522         }
1523
1524
1525         return (PA_THREAD_RETTYPE)(0);
1526 }
1527
1528
1529 ////////////////////////////////////////////////////////////////////////////////////////////
1530 extern void initRudpTimer();
1531 extern void uninitRudpTimer();
1532
1533 int RUDPStart()
1534 {
1535 /*
1536         struct sockaddr_in sai;
1537         int salen;
1538
1539         sockw_r = socket(AF_INET, SOCK_DGRAM, 0);
1540         sockw_s = socket(AF_INET, SOCK_DGRAM, 0);
1541
1542         memset(&sai, 0, sizeof(sai));
1543         sai.sin_family = AF_INET;
1544         sai.sin_addr.s_addr = inet_addr("127.0.0.1");
1545         bind(sockw_r, (struct sockaddr*)&sai, sizeof(sai));
1546         salen = sizeof(sai);
1547         PA_GetSockName(sockw_r, (struct sockaddr*)&sai, &salen);
1548
1549         if(connect(sockw_s, (struct sockaddr*)&sai, sizeof(sai)) < 0)
1550         {
1551                 perror("connect to output notification slot");
1552                 exit(-1);
1553         }
1554 */
1555         PA_MutexInit(mutex_sock_list);
1556         PA_MutexInit(mutex_pkt_pool);
1557         free_pkt = NULL;
1558
1559         hthd = PA_ThreadCreate(_RUDPServiceThread, NULL);
1560         //initRudpTimer();
1561
1562         return 0;
1563 }
1564
1565 int RUDPCleanup()
1566 {
1567         struct list_head *p, *q;
1568
1569         //uninitRudpTimer();
1570
1571         run = 0;
1572         PA_ThreadWaitUntilTerminate(hthd);
1573         PA_ThreadCloseHandle(hthd);
1574         //PA_SocketClose(sockw_r);
1575         //PA_SocketClose(sockw_s);
1576
1577         PA_MutexLock(mutex_sock_list);
1578         list_for_each_safe(p, q, &sock_list)
1579         {
1580                 struct rudp_socket *s = list_entry(p, struct rudp_socket, inst_list);
1581                 if(!list_empty(&s->listen_queue))
1582                 {
1583                         struct list_head *pp, *qq;
1584                         list_for_each_safe(pp, qq, &s->listen_queue)
1585                         {
1586                                 struct rudp_socket *ss = list_entry(pp, struct rudp_socket, accepted_list);
1587                                 _sendReset(ss, (struct sockaddr*)&ss->pcb->peer);
1588                                 _CleanupSocket(ss, 0);
1589                                 list_del(pp);
1590                                 free(ss);
1591                         }
1592                 }
1593                 if(s->state == RS_ESTABLISHED)
1594                         _sendReset(s, (struct sockaddr*)&s->pcb->peer);
1595                 _CleanupSocket(s, 0);
1596                 list_del(p);
1597                 PA_SocketClose(s->udp_sock);
1598                 free(s);
1599         }
1600         PA_MutexUnlock(mutex_sock_list);
1601
1602         PA_MutexUninit(mutex_pkt_pool);
1603         while(free_pkt)
1604         {
1605                 struct rudp_pkt *p = free_pkt;
1606                 free_pkt = free_pkt->next;
1607                 free(p);
1608         }
1609
1610         PA_MutexUninit(mutex_sock_list);
1611
1612         return 0;
1613 }
1614
1615 RUDPSOCKET RUDPSocket()
1616 {
1617         struct rudp_socket *sock = _AllocRudpSocket();
1618         sock->udp_sock = socket(AF_INET, SOCK_DGRAM, 0);
1619         PA_SocketSetNBlk(sock->udp_sock, 1);
1620         PA_MutexLock(mutex_sock_list);
1621         list_add_tail(&sock->inst_list, &sock_list);
1622         PA_MutexUnlock(mutex_sock_list);
1623
1624         return (RUDPSOCKET)sock;
1625 }
1626
1627 RUDPSOCKET RUDPSocketFromUdp(int udpsock)
1628 {
1629         struct rudp_socket *s = _AllocRudpSocket();
1630         s->udp_sock = udpsock;
1631         PA_SocketSetNBlk(udpsock, 1);
1632         PA_MutexLock(mutex_sock_list);
1633         list_add_tail(&s->inst_list, &sock_list);
1634         PA_MutexUnlock(mutex_sock_list);
1635
1636         return (RUDPSOCKET)s;
1637 }
1638
1639 int RUDPSetInvalidPacketCB(RUDPSOCKET sock, NONRUDPPACKETCB pkt_cb, void *p_user)
1640 {
1641         struct rudp_socket *s = (struct rudp_socket*)sock;
1642         if(s->tag != RUDP_SOCKET_TAG) return ERUDP_NOT_SOCKET;
1643         s->non_rudp_pkt_cb = (_NONRUDPPACKETCB)pkt_cb;
1644         s->p_user = p_user;
1645         return 0;
1646 }
1647
1648 int RUDPClose(RUDPSOCKET sock)
1649 {
1650         struct rudp_socket *s = (struct rudp_socket*)sock;
1651         if(s->tag != RUDP_SOCKET_TAG) return ERUDP_NOT_SOCKET;
1652
1653         switch(s->state)
1654         {
1655                 case RS_CLOSED:
1656                         break;
1657                 case RS_LISTEN:
1658                         {
1659                                 struct list_head *p, *q;
1660                                 PA_MutexLock(mutex_sock_list);
1661                                 list_for_each_safe(p, q, &s->listen_queue)
1662                                 {
1663                                         struct rudp_socket *aa = list_entry(p, struct rudp_socket, accepted_list);
1664                                         _sendReset(aa, (struct sockaddr*)&aa->pcb->peer);
1665                                         _CleanupSocket(aa, 0);
1666                                         list_del(p);
1667                                         free(aa);
1668                                 }
1669                                 PA_MutexUnlock(mutex_sock_list);
1670                         }
1671                         break;
1672                 case RS_SYN_SENT:
1673                 case RS_SYN_RCVD:
1674                         _sendReset(s, (struct sockaddr*)&s->pcb->peer);
1675                         break;
1676                 case RS_ESTABLISHED:
1677                         {
1678                                 int i, sb_is_empty = 1;
1679                                 PA_MutexLock(s->mutex_w);
1680                                 for(i=0; i<MAX_PHY_CHANNELS; i++)
1681                                 {
1682                                         struct sndbuf *psb = &s->pcb->channel[i].sbuf;
1683                                         struct rcvbuf *prb = &s->pcb->channel[i].rbuf;
1684                                         if(psb->first != NULL) { sb_is_empty = 0; }
1685
1686                                         for(; prb->head != prb->tail; prb->head = (prb->head+1)%prb->q_size)
1687                                                 if(prb->pkt_q[prb->head])
1688                                                 {
1689                                                         _MBufPutPacket(prb->pkt_q[prb->head]);
1690                                                         prb->pkt_q[prb->head] = NULL;
1691                                                 }
1692                                 }
1693                                 if(sb_is_empty)
1694                                 {
1695                                         _sendFin(s);
1696                                         s->state = RS_FIN_WAIT_1;
1697                                         s->timer[RT_KEEP] = RTT_MIN * RTV_KEEP_CLOSE;
1698                                 }
1699                                 else
1700                                 {
1701                                         s->state = RS_FIN_QUEUED;
1702                                 }
1703                                 PA_MutexUnlock(s->mutex_w);
1704                         }
1705                         break;
1706                 case RS_CLOSE_WAIT:
1707                         break;
1708                 case RS_FIN_QUEUED:
1709                 case RS_FIN_WAIT_1:
1710                 case RS_FIN_WAIT_2:
1711                 case RS_CLOSING:
1712                 case RS_TIME_WAIT:
1713                         return ERUDP_NOT_ALLOWED;
1714         }
1715
1716         /* NOTE: 
1717          *      Remove from inst_list first, then cleanup the resources.
1718          *      If we are managed to maintain the closing states in future, cleanup
1719          *      should be executed in timerProc()
1720          */
1721
1722         if(1)//s->state < RS_ESTABLISHED)
1723         {
1724                 PA_MutexLock(mutex_sock_list);
1725                 _CleanAndFreeSocket(s);
1726                 PA_MutexUnlock(mutex_sock_list);
1727         }
1728
1729         return 0;
1730 }
1731
1732 int RUDPListen(RUDPSOCKET sock, int n)
1733 {
1734         struct rudp_socket *s = (struct rudp_socket*)sock;
1735         if(s->tag != RUDP_SOCKET_TAG) return ERUDP_NOT_SOCKET;
1736
1737         if(s->state != RS_CLOSED) return ERUDP_NOT_ALLOWED;
1738         INIT_LIST_HEAD(&s->listen_queue);
1739         s->state = RS_LISTEN;
1740
1741 #if defined(_WIN32) || defined(ARM_UCOS_LWIP)
1742         {
1743         int opt;
1744         opt = 100*1024;//1500*s->pcb->channel[0].sbuf.rwin_size/2;
1745         setsockopt(s->udp_sock, SOL_SOCKET, SO_RCVBUF, (const char*)&opt, sizeof(int));
1746         //setsockopt(s->udp_sock, SOL_SOCKET, SO_SNDBUF, &opt, sizeof(int));
1747         }
1748 #endif
1749
1750         return 0;
1751 }
1752
1753 int RUDPAccept(RUDPSOCKET sock, RUDPSOCKET *accepted, struct sockaddr *addr, int *addrlen)
1754 {
1755         struct rudp_socket *s, *a;
1756         struct list_head *p, *q;
1757
1758         s = (struct rudp_socket*)sock;
1759         if(s->tag != RUDP_SOCKET_TAG) return ERUDP_NOT_SOCKET;
1760
1761         *accepted = NULL;
1762 wait:
1763         PA_MutexLock(s->mutex_r);
1764 #if defined(_WIN32) || defined(ARM_UCOS_LWIP)
1765         if(list_empty(&s->listen_queue))
1766         {
1767                 PA_MutexUnlock(s->mutex_r);
1768                 PA_EventWait(s->event_r);
1769                 PA_MutexLock(s->mutex_r);
1770         }
1771 #else
1772         while(list_empty(&s->listen_queue))
1773                 pthread_cond_wait(&s->event_r, &s->mutex_r);
1774 #endif
1775         PA_MutexUnlock(s->mutex_r);
1776
1777
1778         PA_MutexLock(mutex_sock_list);
1779
1780         list_for_each_safe(p, q, &s->listen_queue)
1781         {
1782                 a = list_entry(p, struct rudp_socket, listen_queue);
1783                 if(a->state == RS_ESTABLISHED)
1784                 {
1785                         list_del(p);
1786
1787                         INIT_LIST_HEAD(&a->accepted_list);
1788                         list_add_tail(&a->accepted_list, &s->accepted_list);
1789
1790                         INIT_LIST_HEAD(&a->listen_queue);
1791                         *accepted = (RUDPSOCKET)a;
1792                         memcpy(addr, &a->pcb->peer, sizeof(struct sockaddr));
1793                         *addrlen = sizeof(struct sockaddr);
1794
1795                         break;
1796                 }
1797         }
1798
1799         PA_MutexUnlock(mutex_sock_list);
1800
1801         if(!*accepted)
1802         {
1803                 if(s->flags & RF_NBLK)
1804                         return ERUDP_AGAIN;
1805                 else goto wait;
1806         }
1807
1808         return 0;
1809 }
1810
1811 int RUDPBind(RUDPSOCKET sock, const struct sockaddr *addr, int addrlen)
1812 {
1813         struct rudp_socket *s = (struct rudp_socket*)sock;
1814         if(s->tag != RUDP_SOCKET_TAG) return ERUDP_NOT_SOCKET;
1815
1816         if(bind(s->udp_sock, addr, addrlen) == 0) return 0;
1817         return ERUDP_BIND;
1818 }
1819
1820
1821 /* For simultaneous open:
1822  *      1. Call RUDPBind(...) to bind to a local port, call RUDPAccept(...) on NEITHER sides
1823  *      2. Call RUDPConnect(...) on both sides
1824  */
1825 int RUDPConnect(RUDPSOCKET sock, const struct sockaddr* addr, int addr_len)
1826 {
1827         struct rudp_socket *s;
1828         int sa_len;
1829
1830         s = (struct rudp_socket*)sock;
1831         if(s->tag != RUDP_SOCKET_TAG) return ERUDP_NOT_SOCKET;
1832         if(s->state == RS_ESTABLISHED) return ERUDP_CONNECTED;
1833         if(s->state == RS_SYN_SENT) return ERUDP_IN_PROGRESS;
1834         if(s->state != RS_CLOSED/* || s->pcb*/) return ERUDP_NOT_ALLOWED;
1835
1836
1837         s->err = 0;
1838         if(!s->pcb) s->pcb = _AllocRudpPcb(s->rcvbuf_sz, INITIAL_SEQ_NO, 0, 1);
1839         memcpy(&s->pcb->peer, addr, sizeof(struct sockaddr));
1840 #if 0
1841         if(connect(s->udp_sock, addr, addr_len) == 0)
1842                 s->connected = TRUE;
1843         else
1844                 dbg_msg("call connect() failed.\n");
1845 #endif
1846         sa_len = sizeof(struct sockaddr_in);
1847         PA_GetSockName(s->udp_sock, (struct sockaddr*)&s->pcb->local, &sa_len);
1848         s->state = RS_SYN_SENT;
1849         s->timer[RT_KEEP] = conn_backoff[0];
1850
1851         //send initial SYN
1852         _sendSyn(s);
1853         s->pcb->retr_cnt = 0;
1854
1855         if(s->flags & RF_NBLK)
1856                 return ERUDP_AGAIN;
1857
1858 #if defined(_WIN32) || defined(ARM_UCOS_LWIP)
1859         PA_EventWait(s->event_w);
1860 #else
1861         PA_MutexLock(s->mutex_w);
1862         while(s->state == RS_SYN_SENT)
1863                 pthread_cond_wait(&s->event_w, &s->mutex_w);
1864         PA_MutexUnlock(s->mutex_w);
1865 #endif  
1866
1867         if(s->state == RS_ESTABLISHED)
1868         {
1869 #if 1
1870                 int opt = 0;
1871                 opt = 1500*128;
1872                 setsockopt(s->udp_sock, SOL_SOCKET, SO_RCVBUF, (const char*)&opt, sizeof(int));
1873 #endif
1874
1875                 return 0;
1876         }
1877         else
1878                 return ERUDP_CONN_FAILED;
1879 }
1880
1881 /** Set rudp socket to connected state(RS_ESTABLSHED) with default setting(receiver's buffer, ...)
1882  */
1883 int RUDPConnected(RUDPSOCKET sock, const struct sockaddr* addr, int peer_rbuf_sz)
1884 {
1885         struct rudp_socket *s;
1886         int sa_len, opt;
1887
1888         s = (struct rudp_socket*)sock;
1889         if(s->tag != RUDP_SOCKET_TAG) return ERUDP_NOT_SOCKET;
1890         if(s->state == RS_ESTABLISHED) return ERUDP_CONNECTED;
1891         if(s->state == RS_SYN_SENT) return ERUDP_IN_PROGRESS;
1892         if(s->state != RS_CLOSED/* || s->pcb*/) return ERUDP_NOT_ALLOWED;
1893
1894
1895         s->err = 0;
1896         if(peer_rbuf_sz) s->rcvbuf_sz = peer_rbuf_sz;
1897         if(!s->pcb) s->pcb = _AllocRudpPcb(s->rcvbuf_sz, INITIAL_SEQ_NO, 0, 1);
1898         memcpy(&s->pcb->peer, addr, sizeof(struct sockaddr));
1899 #if 0
1900         if(connect(s->udp_sock, addr, sizeof(struct sockaddr)) == 0)
1901                 s->connected = TRUE;
1902         else
1903                 dbg_msg("call connect() failed.\n");
1904 #endif
1905         sa_len = sizeof(struct sockaddr_in);
1906         PA_GetSockName(s->udp_sock, (struct sockaddr*)&s->pcb->local, &sa_len);
1907         //PA_MutexLock(s->mutex_w);
1908         s->state = RS_ESTABLISHED;
1909         SETEVENT(s->event_w);
1910         //PA_MutexUnlock(s->mutex_w);
1911 #if 1
1912         opt = 1500*128;
1913         setsockopt(s->udp_sock, SOL_SOCKET, SO_RCVBUF, (const char*)&opt, sizeof(int));
1914 #endif
1915         return 0;
1916 }
1917
1918 //! \retval >=0 bytes sent
1919 //! \retval <0 error code
1920 int RUDPSendV(RUDPSOCKET sock, int chno, const PA_IOVEC *v, unsigned int size, int flags)
1921 {
1922         struct rudp_socket *s;
1923         struct sndbuf *ps;
1924         unsigned int i, len, byt_sent;
1925                 
1926         len = byt_sent = 0;
1927         for(i=0; i<size; i++) len += PA_IoVecGetLen(&v[i]);
1928         if(len == 0) return 0;
1929
1930         s = (struct rudp_socket*)sock;
1931         if(s->tag != RUDP_SOCKET_TAG) return ERUDP_NOT_SOCKET;
1932         if(s->err) return s->err;
1933         if(s->state != RS_ESTABLISHED) return ERUDP_NO_CONN;
1934
1935
1936         ps = &s->pcb->channel[PHY_CHN(chno)].sbuf;
1937         PA_MutexLock(s->mutex_w);
1938         if(s->state == RS_DEAD) 
1939         {
1940                 PA_MutexLock(s->mutex_w);
1941                 return s->err;
1942         }
1943         
1944
1945 #if defined(_WIN32) || defined(ARM_UCOS_LWIP)
1946         if(ps->n_pkt >= ps->max_pkts && s->state != RS_DEAD)
1947         {
1948                 if((flags & RUDPMSG_DONTWAIT) || (s->flags & RF_NBLK))
1949                 {
1950                         PA_MutexUnlock(s->mutex_w);
1951                         return ERUDP_AGAIN;
1952                 }
1953                 PA_MutexUnlock(s->mutex_w);
1954                 PA_EventWait(s->event_w);
1955                 PA_MutexLock(s->mutex_w);
1956         }
1957 #else
1958         while(ps->n_pkt >= ps->max_pkts && s->state != RS_DEAD)
1959         {
1960                 if((flags & RUDPMSG_DONTWAIT) || (s->flags & RF_NBLK))
1961                 {
1962                         PA_MutexUnlock(s->mutex_w);
1963                         return ERUDP_AGAIN;
1964                 }
1965                 pthread_cond_wait(&s->event_w, &s->mutex_w);
1966         }
1967 #endif  
1968         if(s->err == 0)
1969         {
1970                 unsigned int t, copied = 0/*byte copied in an IOVEC*/;
1971                 struct rudp_pkt *last = ps->last;
1972                 i = 0;
1973 #if 1
1974                 //if last packet has the same chno, fill it
1975                 //   <<<-- always has the same chno since we have sending-queue for each chno(20150203)
1976                 if(last && last->trans == 0 && last->hdr.flags.chno == chno)
1977                 {
1978                         for(; i<size && last->len < MAX_DATA_SIZE; i++)
1979                         {
1980                                 t = min(PA_IoVecGetLen(&v[i]), MAX_DATA_SIZE - last->len);
1981                                 memcpy(last->data + last->len, PA_IoVecGetPtr(&v[i]), t);
1982                                 last->len += t;
1983                                 byt_sent += t;
1984                                 if(PA_IoVecGetLen(&v[i]) != t)  //last packet is full, but there still are data in v[i]
1985                                 {
1986                                         copied = t;
1987                                         break;
1988                                 }
1989                         }
1990                 }
1991 #endif
1992                 while(i < size)
1993                 {
1994                         struct rudp_pkt *pkt;
1995
1996                         pkt = _MBufGetPacket();
1997                         if(!pkt) break;
1998
1999                         pkt->hdr.flags.chno = chno;
2000
2001                         for(; i<size && pkt->len < MAX_DATA_SIZE; i++, copied = 0)
2002                         {
2003                                 t = min(PA_IoVecGetLen(&v[i]) - copied, MAX_DATA_SIZE - pkt->len);
2004                                 memcpy(pkt->data + pkt->len, (char*)PA_IoVecGetPtr(&v[i]) + copied, t);
2005                                 pkt->len += t;
2006                                 byt_sent += t;
2007                                 if(PA_IoVecGetLen(&v[i]) - copied != t) //pkt is full
2008                                 {
2009                                         copied += t;
2010                                         break;
2011                                 }
2012                         }
2013                         if(pkt->len == 0)
2014                         {
2015                                 _MBufPutPacket(pkt);
2016                                 continue;
2017                         }
2018
2019                         pkt->seqno = s->pcb->channel[PHY_CHN(chno)].sbuf.seqno++;
2020                         pkt->hdr.seqno = htonl(pkt->seqno);
2021                         if(ps->first)
2022                         {
2023                                 ps->last->next = pkt;
2024                                 ps->last = pkt;
2025                                 //ps->last = ps->last->next = pkt;
2026                                 if(!ps->not_sent) ps->not_sent = ps->last;
2027                         }
2028                         else
2029                                 ps->first = ps->last = ps->not_sent = pkt;
2030                         pkt->next = NULL;
2031
2032                         ps->n_pkt++;
2033                 }
2034                 //signalOutput(s, PHY_CHN(chno));
2035                 //_RudpOutput(s, PHY_CHN(chno), 0);
2036                 while(_RudpOutput(s, PHY_CHN(chno), 0) > 0);
2037         }
2038         else
2039                 byt_sent = s->err;
2040
2041         PA_MutexUnlock(s->mutex_w);
2042
2043         return byt_sent;
2044 }
2045
2046 //! \param priority 0~15. Low value has a higher priority
2047 //! \retval >=0 bytes sent
2048 //! \retval <0 error code
2049 int RUDPSendVEx(RUDPSOCKET sock, int chno, int priority, const PA_IOVEC *v, unsigned int size, int flags)
2050 {
2051         struct rudp_socket *s;
2052         struct sndbuf *ps;
2053         unsigned int i, len, byt_sent;
2054                 
2055         len = byt_sent = 0;
2056         for(i=0; i<size; i++) len += PA_IoVecGetLen(&v[i]);
2057         if(len == 0) return 0;
2058
2059         s = (struct rudp_socket*)sock;
2060         if(s->tag != RUDP_SOCKET_TAG) return ERUDP_NOT_SOCKET;
2061         if(s->err) return s->err;
2062         if(s->state != RS_ESTABLISHED) return ERUDP_NO_CONN;
2063
2064
2065         ps = &s->pcb->channel[PHY_CHN(chno)].sbuf;
2066         PA_MutexLock(s->mutex_w);
2067         if(s->state == RS_DEAD) 
2068         {
2069                 PA_MutexLock(s->mutex_w);
2070                 return s->err;
2071         }
2072         
2073
2074 #if defined(_WIN32) || defined(ARM_UCOS_LWIP)
2075         if(ps->n_pkt >= ps->max_pkts && s->state != RS_DEAD)
2076         {
2077                 if((flags & RUDPMSG_DONTWAIT) || (s->flags & RF_NBLK))
2078                 {
2079                         PA_MutexUnlock(s->mutex_w);
2080                         return ERUDP_AGAIN;
2081                 }
2082                 PA_MutexUnlock(s->mutex_w);
2083                 PA_EventWait(s->event_w);
2084                 PA_MutexLock(s->mutex_w);
2085         }
2086 #else
2087         while(ps->n_pkt >= ps->max_pkts && s->state != RS_DEAD)
2088         {
2089                 if((flags & RUDPMSG_DONTWAIT) || (s->flags & RF_NBLK))
2090                 {
2091                         PA_MutexUnlock(s->mutex_w);
2092                         return ERUDP_AGAIN;
2093                 }
2094                 pthread_cond_wait(&s->event_w, &s->mutex_w);
2095         }
2096 #endif  
2097         if(s->err == 0)
2098         {
2099                 unsigned int t, copied = 0/*byte copied in an IOVEC*/;
2100                 struct rudp_pkt *next_sav, *pos = ps->not_sent;
2101
2102                 if(pos == NULL) pos = ps->last;
2103                 else
2104                 while(pos != ps->last && pos->priority <= priority)
2105                         pos = pos->next;
2106
2107                 i = 0;
2108                 next_sav = pos->next;
2109
2110                 //if the packet has the same priority, fill it.  
2111                 if(pos && pos->trans == 0 && pos->hdr.flags.chno == chno && pos->priority == priority)
2112                 {
2113                         for(; i<size && pos->len < MAX_DATA_SIZE; i++)
2114                         {
2115                                 t = min(PA_IoVecGetLen(&v[i]), MAX_DATA_SIZE - pos->len);
2116                                 memcpy(pos->data + pos->len, PA_IoVecGetPtr(&v[i]), t);
2117                                 pos->len += t;
2118                                 byt_sent += t;
2119                                 if(PA_IoVecGetLen(&v[i]) != t)  //packet is full, but there still are data in v[i]
2120                                 {
2121                                         copied = t;
2122                                         break;
2123                                 }
2124                         }
2125                 }
2126
2127                 while(i < size)
2128                 {
2129                         struct rudp_pkt *pkt;
2130
2131                         pkt = _MBufGetPacket();
2132                         if(!pkt) break;
2133
2134                         pkt->hdr.flags.chno = chno;
2135
2136                         for(; i<size && pkt->len < MAX_DATA_SIZE; i++, copied = 0)
2137                         {
2138                                 t = min(PA_IoVecGetLen(&v[i]) - copied, MAX_DATA_SIZE - pkt->len);
2139                                 memcpy(pkt->data + pkt->len, (char*)PA_IoVecGetPtr(&v[i]) + copied, t);
2140                                 pkt->len += t;
2141                                 byt_sent += t;
2142                                 if(PA_IoVecGetLen(&v[i]) - copied != t) //pkt is full
2143                                 {
2144                                         copied += t;
2145                                         break;
2146                                 }
2147                         }
2148                         if(pkt->len == 0)
2149                         {
2150                                 _MBufPutPacket(pkt);
2151                                 continue;
2152                         }
2153
2154                         pkt->seqno = s->pcb->channel[PHY_CHN(chno)].sbuf.seqno++;
2155                         pkt->hdr.seqno = htonl(pkt->seqno);
2156                         if(ps->first)
2157                         {
2158                                 pos->next = pkt;
2159                                 pos = pkt;
2160                                 if(!ps->not_sent) ps->not_sent = pos;
2161                         }
2162                         else
2163                                 ps->first = ps->last = ps->not_sent = pkt;
2164                         pkt->next = NULL;
2165
2166                         ps->n_pkt++;
2167                 }
2168                 pos->next = next_sav;
2169
2170                 //signalOutput(s, PHY_CHN(chno));
2171                 //_RudpOutput(s, PHY_CHN(chno), 0);
2172                 while(_RudpOutput(s, PHY_CHN(chno), 0) > 0);
2173         }
2174         else
2175                 byt_sent = s->err;
2176
2177         PA_MutexUnlock(s->mutex_w);
2178
2179         return byt_sent;
2180 }
2181
2182 int RUDPSend(RUDPSOCKET sock, int chno, const void *ptr, int len, int flags)
2183 {
2184         struct rudp_socket *s;
2185         struct sndbuf *ps;
2186         int byt_sent = 0;
2187                 
2188         if(len == 0) return 0;
2189         s = (struct rudp_socket*)sock;
2190         if(s->tag != RUDP_SOCKET_TAG) return ERUDP_NOT_SOCKET;
2191         if(s->err) return s->err;
2192         if(s->state != RS_ESTABLISHED) return ERUDP_NO_CONN;
2193
2194
2195         ps = &s->pcb->channel[PHY_CHN(chno)].sbuf;
2196         PA_MutexLock(s->mutex_w);
2197         if(s->state == RS_DEAD) 
2198         {
2199                 PA_MutexLock(s->mutex_w);
2200                 return s->err;
2201         }
2202         
2203
2204         /* Put a packet on the end of sending-queue then return.
2205          * If the sending-queue is full, wait on this queue.
2206          * The actual sending is done in the service thread.
2207          */
2208 #if defined(_WIN32) || defined(ARM_UCOS_LWIP)
2209         while(ps->n_pkt >= ps->max_pkts && s->state != RS_DEAD)
2210         {
2211                 if((flags & RUDPMSG_DONTWAIT) || (s->flags & RF_NBLK))
2212                 {
2213                         PA_MutexUnlock(s->mutex_w);
2214                         return ERUDP_AGAIN;
2215                 }
2216                 PA_MutexUnlock(s->mutex_w);
2217                 PA_EventWait(s->event_w);
2218                 PA_MutexLock(s->mutex_w);
2219         }
2220 #else
2221         while(ps->n_pkt >= ps->max_pkts && s->state != RS_DEAD)
2222         {
2223                 if((flags & RUDPMSG_DONTWAIT) || (s->flags & RF_NBLK))
2224                 {
2225                         PA_MutexUnlock(s->mutex_w);
2226                         return ERUDP_AGAIN;
2227                 }
2228                 pthread_cond_wait(&s->event_w, &s->mutex_w);
2229         }
2230 #endif  
2231
2232         if(s->err == 0)
2233         {
2234                 int t;
2235                 char *data;
2236                 struct rudp_pkt *last, *pkt;
2237
2238                 data = (char*)ptr;
2239                 last = ps->last;
2240
2241                 //Merge small packets with the same chno
2242                 if(last && last->trans == 0 && last->hdr.flags.chno == chno && last->len < MAX_DATA_SIZE)
2243                 {
2244                         t = min(len, MAX_DATA_SIZE - last->len);
2245                         memcpy(last->data + last->len, data, t);
2246                         last->len += t;
2247                         byt_sent += t;
2248                         data += t;
2249                         len -= t;
2250                 }
2251
2252                 while(len)
2253                 {
2254                         pkt = _MBufGetPacket();
2255                         if(!pkt) break;
2256
2257                         pkt->hdr.flags.chno = chno;
2258
2259                         t = min(len, MAX_DATA_SIZE);
2260                         memcpy(pkt->data, data, t);
2261                         pkt->len = t;
2262                         pkt->trans = 0;
2263                         pkt->seqno = ps->seqno++;
2264                         pkt->hdr.seqno = htonl(pkt->seqno);
2265                         if(ps->first)
2266                         {
2267                                 ps->last->next = pkt;
2268                                 ps->last = pkt;
2269                                 //ps->last = ps->last->next = pkt;
2270                                 if(!ps->not_sent) ps->not_sent = ps->last;
2271                         }
2272                         else
2273                                 ps->first = ps->last = ps->not_sent = pkt;
2274                         pkt->next = NULL;
2275
2276                         ps->n_pkt++;
2277                         byt_sent += t;
2278                         len -= t;
2279                 }
2280
2281                 //signalOutput(s, PHY_CHN(chno));
2282                 //_RudpOutput(s, PHY_CHN(chno), 0);
2283                 while(_RudpOutput(s, PHY_CHN(chno), 0) > 0);
2284         }
2285         else
2286                 byt_sent = s->err;
2287
2288         PA_MutexUnlock(s->mutex_w);
2289
2290         //_sendReset(s, &s->pcb->peer);
2291         return byt_sent;
2292 }
2293
2294 int RUDPSendEx(RUDPSOCKET sock, int chno, int priority, const void *ptr, int len, int flags)
2295 {
2296         struct rudp_socket *s;
2297         struct sndbuf *ps;
2298         int byt_sent = 0;
2299                 
2300         if(len == 0) return 0;
2301         s = (struct rudp_socket*)sock;
2302         if(s->tag != RUDP_SOCKET_TAG) return ERUDP_NOT_SOCKET;
2303         if(s->err) return s->err;
2304         if(s->state != RS_ESTABLISHED) return ERUDP_NO_CONN;
2305
2306
2307         ps = &s->pcb->channel[PHY_CHN(chno)].sbuf;
2308         PA_MutexLock(s->mutex_w);
2309         if(s->state == RS_DEAD) 
2310         {
2311                 PA_MutexLock(s->mutex_w);
2312                 return s->err;
2313         }
2314         
2315
2316         /* Put a packet on the end of sending-queue then return.
2317          * If the sending-queue is full, wait on this queue.
2318          * The actual sending is done in the service thread.
2319          */
2320 #if defined(_WIN32) || defined(ARM_UCOS_LWIP)
2321         while(ps->n_pkt >= ps->max_pkts && s->state != RS_DEAD)
2322         {
2323                 if((flags & RUDPMSG_DONTWAIT) || (s->flags & RF_NBLK))
2324                 {
2325                         PA_MutexUnlock(s->mutex_w);
2326                         return ERUDP_AGAIN;
2327                 }
2328                 PA_MutexUnlock(s->mutex_w);
2329                 PA_EventWait(s->event_w);
2330                 PA_MutexLock(s->mutex_w);
2331         }
2332 #else
2333         while(ps->n_pkt >= ps->max_pkts && s->state != RS_DEAD)
2334         {
2335                 if((flags & RUDPMSG_DONTWAIT) || (s->flags & RF_NBLK))
2336                 {
2337                         PA_MutexUnlock(s->mutex_w);
2338                         return ERUDP_AGAIN;
2339                 }
2340                 pthread_cond_wait(&s->event_w, &s->mutex_w);
2341         }
2342 #endif  
2343
2344         if(s->err == 0)
2345         {
2346                 int t;
2347                 char *data;
2348                 struct rudp_pkt *pos, *pkt, *next_sav;
2349
2350                 data = (char*)ptr;
2351                 pos = ps->not_sent;
2352                 while(pos && pos != ps->last && pos->priority <= priority)
2353                         pos = pos->next;
2354
2355                 next_sav = pos->next;
2356
2357                 //Merge small packets with the same chno
2358                 if(pos && pos->trans == 0 && pos->hdr.flags.chno == chno && pos->len < MAX_DATA_SIZE)
2359                 {
2360                         t = min(len, MAX_DATA_SIZE - pos->len);
2361                         memcpy(pos->data + pos->len, data, t);
2362                         pos->len += t;
2363                         byt_sent += t;
2364                         data += t;
2365                 }
2366
2367                 while(byt_sent < len)
2368                 {
2369                         pkt = _MBufGetPacket();
2370                         if(!pkt) break;
2371
2372                         pkt->hdr.flags.chno = chno;
2373
2374                         t = min(len, MAX_DATA_SIZE);
2375                         memcpy(pkt->data, data, t);
2376                         pkt->len = t;
2377                         pkt->trans = 0;
2378                         pkt->seqno = ps->seqno++;
2379                         pkt->hdr.seqno = htonl(pkt->seqno);
2380                         if(ps->first)
2381                         {
2382                                 pos->next = pkt;
2383                                 pos = pkt;
2384                                 if(!ps->not_sent) ps->not_sent = pos;
2385                         }
2386                         else
2387                                 ps->first = ps->last = ps->not_sent = pkt;
2388                         pkt->next = NULL;
2389
2390                         ps->n_pkt++;
2391                         byt_sent += t;
2392                 }
2393
2394                 //signalOutput(s, PHY_CHN(chno));
2395                 //_RudpOutput(s, PHY_CHN(chno), 0);
2396                 while(_RudpOutput(s, PHY_CHN(chno), 0) > 0);
2397         }
2398         else
2399                 byt_sent = s->err;
2400
2401         PA_MutexUnlock(s->mutex_w);
2402
2403         //_sendReset(s, &s->pcb->peer);
2404         return byt_sent;
2405 }
2406 /** Receive a packet
2407     \param chno channel of packet[out]
2408     \param flags ---
2409     \return length of data received
2410 */
2411 int RUDPRecv(RUDPSOCKET sock, int *chno, void *ptr, int len, int flags)
2412 {
2413         struct rudp_socket *s;
2414         struct rudp_pcb *pcb;
2415         struct rcvbuf *prb;
2416         int i, no_data;
2417         int rlen;
2418
2419         s = (struct rudp_socket*)sock;
2420         if(s->tag != RUDP_SOCKET_TAG) return ERUDP_NOT_SOCKET;
2421         if(s->err && s->err != ERUDP_PEER_CLOSED) return s->err;
2422         if(s->state != RS_ESTABLISHED && s->state != RS_CLOSE_WAIT) return ERUDP_NO_CONN;
2423
2424         pcb = s->pcb;
2425         PA_MutexLock(s->mutex_r);
2426         if(s->state == RS_DEAD)
2427         {
2428                 PA_MutexUnlock(s->mutex_r);
2429                 return s->err;
2430         }
2431 wait_data:
2432         no_data=1;
2433 #if defined(_WIN32) || defined(ARM_UCOS_LWIP)
2434         for(i=0; i<MAX_PHY_CHANNELS; i++)
2435         {
2436                 prb = &pcb->channel[i].rbuf;
2437                 if(prb->pkt_q[prb->head]) { no_data = 0; break; }
2438         }
2439         if(no_data)
2440         {
2441                 PA_MutexUnlock(s->mutex_r);
2442                 if(s->state == RS_CLOSE_WAIT) return 0;
2443                 if((flags & RUDPMSG_DONTWAIT) || (s->flags & RF_NBLK))
2444                         return ERUDP_AGAIN;
2445                 PA_EventWait(s->event_r);
2446                 PA_MutexLock(s->mutex_r);
2447         }
2448 #else
2449         while(s->state == RS_ESTABLISHED)
2450         {
2451                 for(i=0; i<MAX_PHY_CHANNELS; i++)
2452                 {
2453                         prb = &pcb->channel[i].rbuf;
2454                         if(prb->pkt_q[prb->head]) { no_data = 0; break; }
2455                 }
2456                 if(!no_data) break;
2457                 if(s->state == RS_CLOSE_WAIT) 
2458                 {
2459                         PA_MutexUnlock(s->mutex_r);
2460                         return 0;
2461                 }
2462                 if((flags & RUDPMSG_DONTWAIT) || (s->flags & RF_NBLK))
2463                 {
2464                         PA_MutexUnlock(s->mutex_r);
2465                         return ERUDP_AGAIN;
2466                 }
2467                 pthread_cond_wait(&s->event_r, &s->mutex_r);
2468         }
2469 #endif  
2470         if(s->err == 0)
2471         {
2472                 rlen = 0;
2473                 for(i=0; i<MAX_PHY_CHANNELS; i++)
2474                 {
2475                         struct rudp_pkt *pkt;
2476
2477                         prb = &pcb->channel[i].rbuf;
2478                         pkt = prb->pkt_q[prb->head];
2479                         if(pkt)
2480                         {
2481                                 if(pkt->len > len)
2482                                 {
2483                                         rlen = len;
2484                                         memcpy(ptr, pkt->pdata, len);
2485                                         pkt->len -= len;
2486                                         pkt->pdata += len;
2487                                 }
2488                                 else
2489                                 {
2490                                         rlen = pkt->len;
2491                                         memcpy(ptr, pkt->pdata, rlen);
2492                                         *chno = pkt->hdr.flags.chno;
2493
2494                                         _MBufPutPacket(pkt);
2495
2496                                         prb->pkt_q[prb->head] = NULL;
2497                                         /* "first_seq" always updates with "head",
2498                                          * and is used to calculate the inserted posistion
2499                                          * when a packet is received
2500                                          */
2501                                         prb->head = (prb->head+1)%prb->q_size;
2502                                         prb->first_seq++;
2503
2504                                         prb->win++;     /**/
2505
2506                                         if(prb->win == 1 && !prb->should_ack)
2507                                         {
2508                                                 prb->should_ack = ACKT_OPENWND;
2509                                                 _RudpOutput(s, PHY_CHN(*chno), 0);
2510                                                 //signalOutput(s, *chno);
2511                                         }
2512                                 }
2513                                 break;
2514                         }
2515                 }
2516                 if(rlen == 0)
2517                 {
2518                         if(s->flags & RF_NBLK)
2519                                 rlen = -ERUDP_AGAIN;
2520                         else
2521                                 goto wait_data;
2522                 }
2523         }
2524         else if(s->err == ERUDP_PEER_CLOSED)
2525                 rlen = 0;
2526         else
2527                 rlen = s->err;
2528         PA_MutexUnlock(s->mutex_r);
2529
2530         return rlen;
2531 }
2532
2533 /** Receive a packet
2534     \param chno channel of packet[out]
2535     \param flags ---
2536     \return length of data received
2537 */
2538 int RUDPRecvChn(RUDPSOCKET sock, int *chno, void *ptr, int len, int flags)
2539 {
2540         struct rudp_socket *s;
2541         struct rudp_pcb *pcb;
2542         struct rcvbuf *prb;
2543         int rlen;
2544
2545         s = (struct rudp_socket*)sock;
2546         if(s->tag != RUDP_SOCKET_TAG) return ERUDP_NOT_SOCKET;
2547         if(s->err && s->err != ERUDP_PEER_CLOSED) return s->err;
2548         if(s->state != RS_ESTABLISHED && s->state != RS_CLOSE_WAIT) return ERUDP_NO_CONN;
2549
2550         pcb = s->pcb;
2551         PA_MutexLock(s->mutex_r);
2552         if(s->state == RS_DEAD)
2553         {
2554                 PA_MutexUnlock(s->mutex_r);
2555                 return s->err;
2556         }
2557         prb = &pcb->channel[PHY_CHN(*chno)].rbuf;
2558
2559 wait_data:
2560 #if defined(_WIN32) || defined(ARM_UCOS_LWIP)
2561         if(!prb->pkt_q[prb->head])
2562         {
2563                 PA_MutexUnlock(s->mutex_r);
2564                 if(s->state == RS_CLOSE_WAIT) return 0;
2565                 if(s->flags & RF_NBLK) return ERUDP_AGAIN;
2566                 PA_EventWait(s->event_r);
2567                 PA_MutexLock(s->mutex_r);
2568         }
2569 #else
2570         while(s->state == RS_ESTABLISHED)
2571         {
2572                 if(prb->pkt_q[prb->head]) break;
2573
2574                 if(s->state == RS_CLOSE_WAIT) 
2575                 {
2576                         PA_MutexUnlock(s->mutex_r);
2577                         return 0;
2578                 }
2579                 if(s->flags & RF_NBLK)
2580                 {
2581                         PA_MutexUnlock(s->mutex_r);
2582                         return ERUDP_AGAIN;
2583                 }
2584                 pthread_cond_wait(&s->event_r, &s->mutex_r);
2585         }
2586 #endif  
2587         if(s->err == 0)
2588         {
2589                 struct rudp_pkt *pkt;
2590                 rlen = 0;
2591                 pkt = prb->pkt_q[prb->head];
2592                 if(pkt)
2593                 {
2594                         if(pkt->len > len)
2595                         {
2596                                 rlen = len;
2597                                 memcpy(ptr, pkt->pdata, len);
2598                                 *chno = pkt->hdr.flags.chno;
2599
2600                                 pkt->len -= len;
2601                                 pkt->pdata += len;
2602                         }
2603                         else
2604                         {
2605                                 rlen = pkt->len;
2606                                 memcpy(ptr, pkt->pdata, rlen);
2607                                 *chno = pkt->hdr.flags.chno;
2608
2609                                 _MBufPutPacket(pkt);
2610
2611                                 prb->pkt_q[prb->head] = NULL;
2612                                 /* "first_seq" always updates with "head",
2613                                  * and is used to calculate the inserted posistion
2614                                  * when a packet is received
2615                                  */
2616                                 prb->head = (prb->head+1)%prb->q_size;
2617                                 prb->first_seq++;
2618
2619                                 prb->win++;     /**/
2620
2621                                 if(prb->win == 1 && !prb->should_ack)
2622                                 {
2623                                         prb->should_ack = ACKT_OPENWND;
2624                                         _RudpOutput(s, PHY_CHN(*chno), 0);
2625                                         //signalOutput(s, *chno);
2626                                 }
2627                         }
2628                 }
2629                 else
2630                 {
2631                         if(s->flags & RF_NBLK)
2632                                 rlen = -ERUDP_AGAIN;
2633                         else
2634                                 goto wait_data;
2635                 }
2636         }
2637         else if(s->err == ERUDP_PEER_CLOSED)
2638                 rlen = 0;
2639         else
2640                 rlen = s->err;
2641         PA_MutexUnlock(s->mutex_r);
2642
2643         return rlen;
2644 }
2645
2646 //return: <0 - failed
2647 //        =0 - not ready
2648 //        >0 - ready
2649 int RUDPSelectSock(RUDPSOCKET sock, int chno, int flag, const struct timeval *timeout)
2650 {
2651         struct rudp_socket *s;
2652 #ifdef __linux__
2653         struct timespec ts;
2654 #endif
2655         s = (struct rudp_socket*)sock;
2656         if(s->tag != RUDP_SOCKET_TAG) return ERUDP_NOT_SOCKET;
2657
2658
2659 #ifdef __linux__
2660         if(timeout)
2661         {
2662                 clock_gettime(CLOCK_REALTIME, &ts);
2663                 ts.tv_sec += timeout->tv_sec;
2664                 ts.tv_nsec += 1000 * timeout->tv_usec;
2665                 if(ts.tv_nsec > 1000000000) {
2666                         ts.tv_nsec -= 1000000000;
2667                         ts.tv_sec ++;
2668                 }
2669         }
2670 #endif
2671
2672         if(flag == RUDPSELECT_READABLE)
2673         {
2674                 struct rcvbuf *prb;
2675                 int no_data;
2676                 PA_MutexLock(s->mutex_r);
2677                 if(s->err == ERUDP_RESETED || s->err == ERUDP_PEER_CLOSED)
2678                 {
2679                         PA_MutexUnlock(s->mutex_r);
2680                         return 1;
2681                 }
2682
2683                 no_data = 1;
2684                 if(no_data/* && s->state == RS_ESTABLISHED*/)
2685                 {
2686                         int i;
2687                         if(s->state == RS_LISTEN)
2688                         {
2689                                 struct list_head *p;
2690                                 list_for_each(p, &s->listen_queue)
2691                                 {
2692                                         struct rudp_socket *ss = list_entry(p, struct rudp_socket, listen_queue);
2693                                         if(ss->state == RS_ESTABLISHED) //established socket, can be returned by RUDPAccept
2694                                         {
2695                                                 no_data = 0;
2696                                                 break;
2697                                         }
2698                                 }
2699                         }
2700                         else if(s->state == RS_ESTABLISHED)
2701                         {
2702                                 for(i=0; i<MAX_PHY_CHANNELS; i++)
2703                                 {
2704                                         if(chno < 0 || chno == i)
2705                                         {
2706                                                 prb = &s->pcb->channel[i].rbuf;
2707                                                 if(prb->pkt_q[prb->head]) { no_data = 0; break; }
2708                                         }
2709                                 }
2710                         }
2711
2712                         if(no_data)
2713                         {
2714 #if defined(_WIN32) || defined(ARM_UCOS_LWIP)
2715                                 PA_MutexUnlock(s->mutex_r);
2716                                 if(timeout)
2717                                         no_data = !PA_EventWaitTimed(s->event_r, timeout->tv_sec*1000+timeout->tv_usec/1000);
2718                                 else {
2719                                         PA_EventWait(s->event_r);
2720                                         no_data = 0;
2721                                 }
2722                                 PA_MutexLock(s->mutex_r);
2723 #else
2724                                 if(timeout)
2725                                         no_data = pthread_cond_timedwait(&s->event_r, &s->mutex_r, &ts) == ETIMEDOUT ? 1 : 0;
2726                                 else
2727                                         no_data = pthread_cond_wait(&s->event_r, &s->mutex_r) != 0;
2728 #endif  
2729                         }
2730                 }
2731
2732                 PA_MutexUnlock(s->mutex_r);
2733                 if(s->err) return s->err;
2734                 else return !no_data;
2735         }
2736
2737
2738         if(flag == RUDPSELECT_WRITABLE) do 
2739         {
2740                 struct sndbuf *ps;
2741                 int writable = 1;
2742
2743                 if(chno < 0) return ERUDP_INVALID;
2744                 if(s->state != RS_ESTABLISHED) break;
2745
2746                 PA_MutexLock(s->mutex_w);
2747                 if(s->state == RS_DEAD) 
2748                 {
2749                         PA_MutexLock(s->mutex_w);
2750                         return s->err;
2751                 }
2752
2753                 ps = &s->pcb->channel[chno].sbuf;
2754                 if(ps->n_pkt >= ps->max_pkts && s->state != RS_DEAD)
2755                 {
2756 #if defined(_WIN32) || defined(ARM_UCOS_LWIP)
2757                         PA_MutexUnlock(s->mutex_w);
2758                         if(timeout)
2759                                 writable = PA_EventWaitTimed(s->event_w, timeout->tv_sec*1000+timeout->tv_usec/1000); 
2760                         else {
2761                                 PA_EventWait(s->event_w);
2762                                 writable = 1;
2763                         }
2764                         PA_MutexLock(s->mutex_w);
2765 #else
2766                         if(timeout)
2767                                 writable = pthread_cond_timedwait(&s->event_w, &s->mutex_w, &ts) == ETIMEDOUT ? 0 : 1;
2768                         else
2769                                 writable = pthread_cond_wait(&s->event_w, &s->mutex_w) == 0;
2770 #endif  
2771                 }
2772
2773                 PA_MutexUnlock(s->mutex_w);
2774                 if(s->err) return s->err;
2775                 else return writable;
2776         } while(0);
2777
2778         return 0;
2779 }
2780
2781 int RUDPSelect(RUDPSOCKCHNO *r_rscs, int *n_rrscs, RUDPSOCKCHNO *w_rscs, int *n_wrscs, 
2782                 RUDPSOCKCHNO *e_rscs, int *n_erscs, const struct timeval *timeout)
2783 {
2784         int i, ii, n;
2785         int nr, nw, ne;
2786         struct list_head *p;
2787         struct rudp_socket *s, *ss;
2788         unsigned int wait_ticks, t0;
2789
2790         struct timeval tv;
2791         int _rfds[64], _wfds[64], _efds[64];
2792         int _nr, _nw, _ne;
2793         fd_set _rfds_, _wfds_, _efds_;
2794         int max_fd = -1;
2795
2796         if(timeout)
2797                 wait_ticks = timeout->tv_sec * 1000 + timeout->tv_usec / 1000;
2798         else
2799                 wait_ticks = ~0UL;
2800
2801         /* Extract udp sockets */
2802         _nr = _nw = _ne = 0;
2803         if(r_rscs)
2804         {
2805                 for(i=0; i<*n_rrscs; i++)
2806                 {
2807                         if(r_rscs[i].sock == NULL)
2808                         {
2809                                 _rfds[_nr++] = r_rscs[i].chno;
2810                                 max_fd = max(max_fd, r_rscs[i].chno);
2811                         }
2812                 }
2813         }
2814         if(w_rscs)
2815         {
2816                 for(i=0; i<*n_wrscs; i++)
2817                 {
2818                         if(w_rscs[i].sock == NULL)
2819                         {
2820                                 _wfds[_nw++] = w_rscs[i].chno;
2821                                 max_fd = max(max_fd, w_rscs[i].chno);
2822                         }
2823                 }
2824         }
2825         if(e_rscs)
2826         {
2827                 for(i=0; i<*n_erscs; i++)
2828                 {
2829                         if(e_rscs[i].sock == NULL)
2830                         {
2831                                 _efds[_ne++] = e_rscs[i].chno;
2832                                 max_fd = max(max_fd, e_rscs[i].chno);
2833                         }
2834                 }
2835         }
2836
2837
2838         nr = nw = ne = 0;
2839         t0 = PA_GetTickCount();
2840         do {
2841                 PA_MutexLock(mutex_sock_list);
2842                 if(r_rscs)
2843                 {
2844                         n = *n_rrscs;
2845                         for(i = 0; i < n; i++)
2846                         {
2847                                 if(r_rscs[i].sock == NULL) continue;
2848                                 s = (struct rudp_socket*)r_rscs[i].sock;
2849                                 if(s->err == ERUDP_RESETED || s->err == ERUDP_PEER_CLOSED)
2850                                 {
2851                                         RUDP_SET(s, -1, r_rscs, nr);
2852                                 }
2853                                 else
2854                                 {
2855                                         if(s->state <= RS_CLOSED || s->state >= RS_FIN_QUEUED) 
2856                                         {
2857                                                 continue;
2858                                                 //PA_MutexUnlock(mutex_sock_list);
2859                                                 //return ERUDP_NOT_SOCKET;
2860                                         }
2861                                         PA_MutexLock(s->mutex_r);
2862                                         if(s->state == RS_LISTEN)
2863                                         {
2864                                                 list_for_each(p, &s->listen_queue)
2865                                                 {
2866                                                         ss = list_entry(p, struct rudp_socket, listen_queue);
2867                                                         if(ss->state == RS_ESTABLISHED) //established socket, can be returned by RUDPAccept
2868                                                         {
2869                                                                 r_rscs[nr++].sock = s;
2870                                                                 break;
2871                                                         }
2872
2873                                                 }
2874                                         }
2875                                         else if(s->state == RS_CLOSE_WAIT)
2876                                         {
2877                                                 RUDP_SET(s, -1, r_rscs, nr);
2878                                         }
2879                                         else
2880                                         {
2881                                                 struct rcvbuf *prb;
2882                                                 for(ii=0; ii<MAX_PHY_CHANNELS; ii++)
2883                                                 {
2884                                                         if(r_rscs[i].chno < 0 || ii == r_rscs[i].chno)
2885                                                         {
2886                                                                 prb = &s->pcb->channel[ii/*r_rscs[i].chno*/].rbuf;
2887                                                                 if(prb->pkt_q[prb->head])
2888                                                                 {
2889                                                                         RUDP_SET(r_rscs[i].sock, ii, r_rscs, nr);
2890                                                                         break;
2891                                                                 }
2892                                                         }
2893                                                 }
2894                                         }
2895                                         PA_MutexUnlock(s->mutex_r);
2896                                 }
2897                         }
2898                         if(nr)  { *n_rrscs = nr; r_rscs[nr].sock = INVALID_RUDPSOCKET; }
2899                 }
2900
2901                 if(w_rscs)
2902                 {
2903                         n = *n_wrscs;
2904                         for(i = 0; i < n; i++)
2905                         {
2906                                 if(w_rscs[i].sock == NULL) continue;
2907                                 s = (struct rudp_socket*)w_rscs[i].sock;
2908                                 if(s->state <= RS_CLOSED || s->state >= RS_FIN_QUEUED)
2909                                 {
2910                                         //PA_MutexUnlock(mutex_sock_list);
2911                                         //return ERUDP_NOT_SOCKET;
2912                                         continue;
2913                                 }
2914                                 PA_MutexLock(s->mutex_w);
2915                                 if(s->state == RS_ESTABLISHED)
2916                                 {
2917                                         for(ii=0; ii<MAX_PHY_CHANNELS; ii++)
2918                                         {
2919                                                 if(w_rscs[i].chno < 0 || w_rscs[i].chno == ii)
2920                                                 {
2921                                                         struct sndbuf *psb = &s->pcb->channel[ii].sbuf;
2922                                                         if(psb->n_pkt < psb->max_pkts)
2923                                                         {
2924                                                                 RUDP_SET(w_rscs[i].sock, ii, w_rscs, nw);
2925                                                                 break;
2926                                                         }
2927                                                 }
2928                                         }
2929                                 }
2930                                 else if(s->state == RS_CLOSE_WAIT)
2931                                 {
2932                                         RUDP_SET(w_rscs[i].sock, -1, w_rscs, nw);
2933                                 }
2934                                 PA_MutexUnlock(s->mutex_w);
2935                         }
2936                         if(nw) { *n_wrscs = nw; w_rscs[nw].sock = INVALID_RUDPSOCKET; }
2937                 }
2938                 if(e_rscs)
2939                 {
2940                         for(i=0; i<*n_erscs; i++)
2941                         {
2942                                 if(e_rscs[i].sock == NULL) continue;
2943                                 s = (struct rudp_socket*)e_rscs[i].sock;
2944                                 if(s->err) RUDP_SET(s, -1, e_rscs, ne);
2945                         }
2946                         if(ne) { *n_erscs = ne; e_rscs[ne].sock = INVALID_RUDPSOCKET; }
2947                 }
2948                 PA_MutexUnlock(mutex_sock_list);
2949
2950                 //if(nr || nw || ne) break;     //normal socket will be starved
2951                 if(_nr || _nw || _ne)
2952                 {
2953                         tv.tv_sec = 0; tv.tv_usec = 0;
2954                         if(_nr) { FD_ZERO(&_rfds_); for(i=0; i<_nr; i++) FD_SET(_rfds[i], &_rfds_); }
2955                         if(_nw) { FD_ZERO(&_wfds_); for(i=0; i<_nw; i++) FD_SET(_wfds[i], &_wfds_); }
2956                         if(_ne) { FD_ZERO(&_efds_); for(i=0; i<_ne; i++) FD_SET(_efds[i], &_efds_); }
2957                         if(select(max_fd+1, _nr?&_rfds_:NULL, _nw?&_wfds_:NULL, _ne?&_efds_:NULL, &tv) > 0)
2958                         {
2959                                 if(_nr) for(i=0; i<_nr; i++)
2960                                         if(FD_ISSET(_rfds[i], &_rfds_))
2961                                         {
2962                                                 r_rscs[nr].sock = NULL;
2963                                                 r_rscs[nr++].chno = _rfds[i];
2964                                         }
2965                                 if(_nw) for(i=0; i<_nw; i++)
2966                                         if(FD_ISSET(_wfds[i], &_wfds_))
2967                                         {
2968                                                 w_rscs[nw].sock = NULL;
2969                                                 w_rscs[nw++].chno = _wfds[i];
2970                                         }
2971                                 if(_ne) for(i=0; i<_ne; i++)
2972                                         if(FD_ISSET(_efds[i], &_efds_))
2973                                         {
2974                                                 e_rscs[ne].sock = NULL;
2975                                                 e_rscs[ne++].chno = _efds[i];
2976                                         }
2977                         }
2978                 }
2979
2980                 if(nr || nw || ne) break;
2981                 PA_Sleep(5);
2982         } while(PA_GetTickCount() - t0 < wait_ticks);
2983
2984         if(n_erscs) *n_erscs = ne;
2985         if(n_rrscs) *n_rrscs = nr;
2986         if(n_wrscs) *n_wrscs = nw;
2987
2988         return nr + nw + ne;
2989 }
2990
2991 int RUDP_FD_ISSET(int fd, const RUDPSOCKCHNO *prc, int size)
2992 {
2993         int i;
2994         if(fd < 0) return 0;
2995         for(i=0; i<size; i++)
2996         {
2997                 if(prc[i].sock == NULL && prc[i].chno == fd) return 1;
2998         }
2999         return 0;
3000 }
3001
3002 int RUDP_ISSET(RUDPSOCKET s, const RUDPSOCKCHNO *prc, int size)
3003 {
3004         int i;
3005         if(s == INVALID_RUDPSOCKET) return 0;
3006         for(i=0; i<size; i++)
3007         {
3008                 if(prc[i].sock == s) return 1;
3009         }
3010         return 0;
3011 }
3012
3013 int RUDPGetSockOpt(RUDPSOCKET sock, int opt, void *optval, int *optlen)
3014 {
3015         struct rudp_socket *s = (struct rudp_socket*)sock;
3016         if(s->tag != RUDP_SOCKET_TAG) return ERUDP_NOT_SOCKET;
3017
3018         switch(opt)
3019         {
3020         case OPT_UDP_SNDBUF:
3021                 if(*optlen != sizeof(int)) return ERUDP_INVALID;
3022                 PA_GetSockOpt(s->udp_sock, SOL_SOCKET, SO_SNDBUF, (char*)&opt, optlen);
3023                 return 0;
3024         case OPT_UDP_RCVBUF:
3025                 if(*optlen != sizeof(int)) return ERUDP_INVALID;
3026                 PA_GetSockOpt(s->udp_sock, SOL_SOCKET, SO_RCVBUF, (char*)&opt, optlen);
3027                 return 0;
3028         case OPT_RUDP_SNDBUF:
3029                 if(*optlen != sizeof(int)) return ERUDP_INVALID;
3030                 *((int*)optval) = s->pcb->channel[0].sbuf.max_pkts;
3031                 break;
3032         case OPT_RUDP_RCVBUF:
3033                 if(*optlen != sizeof(int)) return ERUDP_INVALID;
3034                 *((int*)optval) = s->pcb->channel[0].rbuf.q_size;
3035                 break;
3036         case OPT_LINGER:
3037         //case OPT_MSS:
3038         case OPT_SNDTIMEO:
3039         case OPT_RCVTIMEO:
3040                 break;
3041         case OPT_ADHOC:
3042                 if(*optlen != sizeof(int)) return ERUDP_INVALID;
3043                 *((int*)optval) = (s->flags & RF_ADHOC)?1:0;
3044                 break;
3045
3046         case OPT_NBLK:
3047                 if(*optlen != sizeof(int)) return ERUDP_INVALID;
3048                 *((int*)optval) = (s->flags & RF_NBLK)?1:0;
3049                 break;
3050
3051         case OPT_REUSEADDR:
3052                 if(*optlen != sizeof(int)) return ERUDP_INVALID;
3053                 PA_GetSockOpt(s->udp_sock, SOL_SOCKET, SO_REUSEADDR, (char*)optval, optlen);
3054                 break;
3055         case OPT_ERR:
3056                 if(*optlen != sizeof(int)) return ERUDP_INVALID;
3057                 *((int*)optval) = s->err;
3058
3059         default:
3060                 return ERUDP_INVALID;
3061         }
3062         return 0;
3063 }
3064
3065 int RUDPSetSockOpt(RUDPSOCKET sock, int opt, const void *optval, int optlen)
3066 {
3067         int i, val;
3068         struct rudp_socket *s = (struct rudp_socket*)sock;
3069         if(s->tag != RUDP_SOCKET_TAG) return ERUDP_NOT_SOCKET;
3070
3071         switch(opt)
3072         {
3073         case OPT_UDP_SNDBUF:
3074                 if(optlen != sizeof(int)) return ERUDP_INVALID;
3075                 setsockopt(s->udp_sock, SOL_SOCKET, SO_SNDBUF, (char*)&opt, optlen);
3076                 break;
3077         case OPT_UDP_RCVBUF:
3078                 if(optlen != sizeof(int)) return ERUDP_INVALID;
3079                 setsockopt(s->udp_sock, SOL_SOCKET, SO_RCVBUF, (char*)&opt, optlen);
3080                 break;
3081         case OPT_RUDP_SNDBUF:
3082                 if(optlen != sizeof(int)) return ERUDP_INVALID;
3083                 if(s->pcb)
3084                 {
3085                         val = *((int*)optval);
3086                         if(val > MAX_WINDOW) val = MAX_WINDOW;
3087                         if(val < 64) val = 64;
3088                         for(i=0; i<MAX_PHY_CHANNELS; i++)
3089                                 s->pcb->channel[i].sbuf.max_pkts = val;
3090                 }
3091                 break;
3092         case OPT_RUDP_RCVBUF:
3093                 if(optlen != sizeof(int)) return ERUDP_INVALID;
3094                 if(!s->pcb && s->state == RS_CLOSED)
3095                 {
3096                         val = *((int*)optval);
3097                         if(val > MAX_WINDOW) val = MAX_WINDOW;
3098                         if(val < 64) val = 64;
3099                         s->rcvbuf_sz = val;
3100                 }
3101                 break;
3102         case OPT_LINGER:
3103         //case OPT_MSS:
3104         case OPT_SNDTIMEO:
3105         case OPT_RCVTIMEO:
3106                 break;
3107         case OPT_ADHOC:
3108                 if(optlen != sizeof(int)) return ERUDP_INVALID;
3109                 if(s->state != RS_CLOSED || s->pcb) return ERUDP_NOT_ALLOWED;
3110                 if(*((int*)optval)) s->flags |= RF_ADHOC;
3111                 else s->flags &= ~RF_ADHOC;
3112
3113         case OPT_REUSEADDR:
3114                 if(optlen != sizeof(int)) return ERUDP_INVALID;
3115                 setsockopt(s->udp_sock, SOL_SOCKET, SO_REUSEADDR, (char*)optval, optlen);
3116                 break;
3117
3118         case OPT_NBLK:
3119                 if(optlen != sizeof(int)) return ERUDP_INVALID;
3120                 if(s->state < RS_CLOSED) return ERUDP_NOT_ALLOWED;
3121                 if(*((int*)optval)) s->flags |= RF_NBLK;
3122                 else s->flags &= ~RF_NBLK;
3123                 break;
3124
3125         default:
3126                 return ERUDP_INVALID;
3127         }
3128         return 0;
3129 }
3130
3131 int RUDPGetSockName(RUDPSOCKET sock, struct sockaddr *name)
3132 {
3133         struct rudp_socket *s = (struct rudp_socket*)sock;
3134         socklen_t len = sizeof(struct sockaddr);
3135         return getsockname(s->udp_sock, name, &len);
3136 }
3137
3138 int RUDPGetPeerName(RUDPSOCKET sock, struct sockaddr *name)
3139 {
3140         struct rudp_socket *s = (struct rudp_socket*)sock;
3141         if(s->pcb)
3142         {
3143                 memcpy(name, &s->pcb->peer, sizeof(struct sockaddr));
3144                 return 0;
3145         }
3146         memset(name, 0, sizeof(struct sockaddr));
3147         return 0;
3148 }
3149