1 /*--------------------------------------------------------------------------
2   Project:  HorizonSDK
3   File:     rdt_ReceiverImpl.cpp
4   Copyright 2009 Nintendo. All rights reserved.
5   These coded instructions, statements, and computer programs contain
6   proprietary information of Nintendo of America Inc. and/or Nintendo
7   Company Ltd., and are protected by Federal copyright law. They may
8   not be disclosed to third parties or copied or duplicated in any form,
9   in whole or in part, without the prior written consent of Nintendo.
10   $Date:: 2010-09-14#$
11   $Rev: 25753 $
12   $Author: hiratsu_daisuke $
13  *-------------------------------------------------------------------------
14 
15 
16 */
17 
18 #include "stdafx.h"
19 
20 #include "rdt_ReceiverImpl.h"
21 
22 #include <nn/rdt/CTR/rdt_define.h>
23 #include <nn/rdt/CTR/rdt_Result.h>
24 
25 
26 namespace
27 {
28 
29 }  // End of anonymous namespace
30 
31 namespace nn { namespace rdt { namespace CTR {
32 
33 
34 // Base class for "State"
35 class ReceiverStateBase{
36 public:
~ReceiverStateBase(void)37     virtual ~ReceiverStateBase(void){}
38 
39     virtual void initialize(ReceiverImpl *pReceiver); // Called when this state is started
40     virtual void finalize  (ReceiverImpl *pReceiver); // Called when this state is finished
41     virtual void update    (ReceiverImpl *pReceiver);
42     virtual enum ReceiverState getStatus(void) const = 0;
43 
44 protected:
ReceiverStateBase(void)45     ReceiverStateBase(void){}
46 };
47 
48 
initialize(ReceiverImpl * pReceiver)49 void ReceiverStateBase::initialize(ReceiverImpl *pReceiver)
50 {
51     (void)pReceiver;
52 }
53 
54 
finalize(ReceiverImpl * pReceiver)55 void ReceiverStateBase::finalize(ReceiverImpl *pReceiver)
56 {
57     (void)pReceiver;
58 }
59 
60 
update(ReceiverImpl * pReceiver)61 void ReceiverStateBase::update(ReceiverImpl *pReceiver)
62 {
63     (void)pReceiver;
64 }
65 
66 
67 class ReceiverStateWaiting : public ReceiverStateBase{
68 public:
69     static ReceiverStateBase* getInstance(void);
70     virtual void update(ReceiverImpl *pReceiver);
71     virtual enum ReceiverState getStatus(void) const;
72 
73 protected:
ReceiverStateWaiting(void)74     ReceiverStateWaiting(void){}
75 };
76 
77 
78 class ReceiverStateOpened : public ReceiverStateBase{
79 public:
80     static ReceiverStateBase* getInstance(void);
81     virtual void update(ReceiverImpl *pReceiver);
82     virtual enum ReceiverState getStatus(void) const;
83 
84 protected:
ReceiverStateOpened(void)85     ReceiverStateOpened(void){}
86 };
87 
88 
89 class ReceiverStateWaitingFinished : public ReceiverStateBase{
90 public:
91     static ReceiverStateBase* getInstance(void);
92     virtual void update(ReceiverImpl *pReceiver);
93     virtual enum ReceiverState getStatus(void) const;
94 
95 protected:
ReceiverStateWaitingFinished(void)96     ReceiverStateWaitingFinished(void){}
97 };
98 
99 
100 class ReceiverStateFinished : public ReceiverStateBase{
101 public:
102     static ReceiverStateBase* getInstance(void);
103     virtual void update(ReceiverImpl *pReceiver);
104     virtual enum ReceiverState getStatus(void) const;
105 
106 protected:
ReceiverStateFinished(void)107     ReceiverStateFinished(void){}
108 };
109 
110 
111 class ReceiverStateClosed : public ReceiverStateBase{
112 public:
113     static ReceiverStateBase* getInstance(void);
114     virtual void initialize(ReceiverImpl *pReceiver);
115     virtual void update    (ReceiverImpl *pReceiver);
116     virtual enum ReceiverState getStatus(void) const;
117 
118 protected:
ReceiverStateClosed(void)119     ReceiverStateClosed(void){}
120 };
121 
122 
123 // The following is an implementation of an inherited class.
124 
getInstance(void)125 ReceiverStateBase* ReceiverStateWaiting::getInstance(void)
126 {
127     static ReceiverStateWaiting s_instance;
128     return &s_instance;
129 }
130 
131 
getStatus(void) const132 enum ReceiverState ReceiverStateWaiting::getStatus(void) const
133 {
134     return RECEIVER_STATE_WAITING;
135 }
136 
137 
update(ReceiverImpl * pReceiver)138 void ReceiverStateWaiting::update(ReceiverImpl *pReceiver)
139 {
140     ASSERT(pReceiver!=NULL);
141 
142     //Process here if segment is received.
143     Segment seg;
144     if(pReceiver->pullSegment(&seg).IsSuccess())
145     {
146         if(seg.IsRst())
147         {
148             // Per the TCP RFC, it is described that RST received during a LISTEN state should be ignored.
149             //Therefore, nothing is done here.
150         }
151         else if(seg.IsSyn())
152         {
153             // If this is a proper connection request from a remote source, ACK is returned.
154 
155             // Set receive buffer
156             pReceiver->m_recvBuf.SetInitialSequenceNumber(seg.GetSeqNumber());
157 
158             // Response to SYN.
159             pReceiver->putSynAckSegment(seg.GetSeqNumber() + 1);
160             pReceiver->setNextState(ReceiverStateOpened::getInstance());
161         }
162     }
163 }
164 
165 
getInstance(void)166 ReceiverStateBase* ReceiverStateOpened::getInstance(void)
167 {
168     static ReceiverStateOpened s_instance;
169     return &s_instance;
170 }
171 
172 
getStatus(void) const173 enum ReceiverState ReceiverStateOpened::getStatus(void) const
174 {
175     return RECEIVER_STATE_OPENED;
176 }
177 
178 
update(ReceiverImpl * pReceiver)179 void ReceiverStateOpened::update(ReceiverImpl *pReceiver)
180 {
181     ASSERT(pReceiver!=NULL);
182 
183     //Process here if segment is received.
184     Segment seg;
185     if(pReceiver->pullSegment(&seg).IsSuccess())
186     {
187         // First, RST bit check
188         if(seg.IsRst())
189         {
190             pReceiver->setNextState(ReceiverStateClosed::getInstance());
191             pReceiver->errorHandling(ResultResetReceived());
192             return;
193         }
194 
195         // Has the segment with the expected sequence number arrived?
196         ReceiveBuffer &rBuf = pReceiver->m_recvBuf;
197         if(seg.GetSeqNumber()==rBuf.GetLatestSequenceNumber()+1)
198         {
199             if(seg.IsData())
200             {
201                 bool result = rBuf.Push(seg.payload, seg.GetDataLength());
202                 if(result)
203                 {
204                     // Data has been stored in the receive buffer without problems.
205                     // In the existing implementation, the ACK is returned, and as a result it is nothing but a ACK packet of the reception side.
206                     // So, returning the ACK here was eliminated.
207                 }
208                 else
209                 {
210                     LOG("Received data segment, but could not return ACK because receive buffer did not have enough space.\n");
211                 }
212             }
213             else if(seg.IsFin())
214             {
215                 // ACK transmission for the FIN segment
216                 pReceiver->putFinAckSegment(seg.GetSeqNumber() + 1);
217                 pReceiver->setNextState(ReceiverStateWaitingFinished::getInstance());
218             }
219             else
220             {
221                 seg.PrintDebugInfo();
222                 PANIC("It seems that SEQ number is valid, but unexpected segment.  It is not DATA, nor FIN.");
223             }
224         }
225         else if(seg.GetSeqNumber()==rBuf.GetLatestSequenceNumber())
226         {
227             // If no response for Syn arrives, it may be considered that the Sender resends a Syn request.
228             // Handling for this case.
229             if(seg.IsSyn())
230             {
231                 // Response to SYN.
232                 pReceiver->putSynAckSegment(seg.GetSeqNumber() + 1);
233             }
234         }
235 
236         else
237         {
238             VERBOSE("Unexpected SEQ number. (%d)\n", seg.GetSeqNumber());
239             VERBOSE("SEQ number %d is expected.\n", rBuf.GetLatestSequenceNumber()+1);
240             VERBOSE("Received segment will be ignored.\n");
241 
242 #if 0
243             // Because it was not an expected segment, the possibility of a packet loss is suspected.
244             // For now, return ACK quickly for the portion received to this point.
245             pReceiver->putAckSegment();
246 
247             // If the above code is entered, it actually made it slower. Probably because there are a lot of ACK packets issued ...
248 #endif
249         }
250     }
251 }
252 
253 
getInstance(void)254 ReceiverStateBase* ReceiverStateWaitingFinished::getInstance(void)
255 {
256     static ReceiverStateWaitingFinished s_instance;
257     return &s_instance;
258 }
259 
260 
getStatus(void) const261 enum ReceiverState ReceiverStateWaitingFinished::getStatus(void) const
262 {
263     return RECEIVER_STATE_WAITING_FINISHED;
264 }
265 
266 
update(ReceiverImpl * pReceiver)267 void ReceiverStateWaitingFinished::update(ReceiverImpl *pReceiver)
268 {
269     // These return ACK for FIN, but it is not assured that the ACK has arrived to the other party even if the Finished state is entered.
270     //
271     // To determine if the ACK arrived at the other party, you must confirm that no resend packet has arrived from the other party after some time has passed.
272     //
273 
274     ASSERT(pReceiver!=NULL);
275 
276     //Process here if segment is received.
277     Segment seg;
278     if(pReceiver->pullSegment(&seg).IsSuccess())
279     {
280         // RST bit check
281         if(seg.IsRst())
282         {
283             pReceiver->setNextState(ReceiverStateClosed::getInstance());
284             pReceiver->errorHandling(ResultResetReceived());
285             return;
286         }
287 
288         // Has FIN segment arrived?
289         ReceiveBuffer &rBuf = pReceiver->m_recvBuf;
290         if(seg.GetSeqNumber()==rBuf.GetLatestSequenceNumber()+1)
291         {
292             if(seg.IsFin())
293             {
294                 pReceiver->putFinAckSegment(seg.GetSeqNumber() + 1);
295             }
296             else
297             {
298                 seg.PrintDebugInfo();
299                 PANIC("Sequence number is valid, but FIN is not included.\n");
300             }
301         }
302         else
303         {
304 //            seg.PrintDebugInfo();
305             LOG("Segment with unexpected sequence number.  Ignored.\n");
306         }
307     }
308 
309     // State transition after timeout determination.
310     if(pReceiver->isSenderClosed())
311     {
312         pReceiver->setNextState(ReceiverStateFinished::getInstance());
313     }
314 }
315 
316 
getInstance(void)317 ReceiverStateBase* ReceiverStateFinished::getInstance(void)
318 {
319     static ReceiverStateFinished s_instance;
320     return &s_instance;
321 }
322 
323 
getStatus(void) const324 enum ReceiverState ReceiverStateFinished::getStatus(void) const
325 {
326     return RECEIVER_STATE_FINISHED;
327 }
328 
329 
update(ReceiverImpl * pReceiver)330 void ReceiverStateFinished::update(ReceiverImpl *pReceiver)
331 {
332     ASSERT(pReceiver!=NULL);
333 
334     //Process here if segment is received.
335     Segment seg;
336     if(pReceiver->pullSegment(&seg).IsSuccess())
337     {
338         // TODO: Should send RST for segments that do not include RST.
339         PANIC("State is FINISHED, but received segment from remote!\n");
340     }
341 }
342 
343 
344 
getInstance(void)345 ReceiverStateBase* ReceiverStateClosed::getInstance(void)
346 {
347     static ReceiverStateClosed s_instance;
348     return &s_instance;
349 }
350 
351 
getStatus(void) const352 enum ReceiverState ReceiverStateClosed::getStatus(void) const
353 {
354     return RECEIVER_STATE_CLOSED;
355 }
356 
357 
initialize(ReceiverImpl * pReceiver)358 void ReceiverStateClosed::initialize(ReceiverImpl *pReceiver)
359 {
360     ASSERT(pReceiver!=NULL);
361 
362     pReceiver->clear();
363 }
364 
365 
update(ReceiverImpl * pReceiver)366 void ReceiverStateClosed::update(ReceiverImpl *pReceiver)
367 {
368     ASSERT(pReceiver!=NULL);
369 
370     // For segments (not including RST) received while in CLOSED state, respond with RST
371     Segment seg;
372     if(pReceiver->pullSegment(&seg).IsSuccess() && !seg.IsRst())
373     {
374         LOG("Receiver is in CLOSED state, but received segment.  RST will be sent.\n");
375         if(seg.IsAck())
376         {
377             pReceiver->sendRstSegment(seg.GetAckNumber());
378         }
379         else
380         {
381             const u32 SEQ = 0;
382             const u32 ACK = seg.GetSeqNumber() + seg.GetSegmentLength();
383             pReceiver->sendRstAckSegment(SEQ, ACK);
384         }
385     }
386 }
387 
388 
389 
390 //
ReceiverImpl(void)391 ReceiverImpl::ReceiverImpl(void) throw()
392      :m_initialized(false)
393 {
394 }
395 
396 
397 //
~ReceiverImpl(void)398 ReceiverImpl::~ReceiverImpl(void)
399 {
400     Finalize();
401 }
402 
403 
404 #ifdef _WIN32
Initialize(SOCKET sock,void * pRecvBuf,u16 recvBufSize)405 nn::Result ReceiverImpl::Initialize(SOCKET sock, void *pRecvBuf, u16 recvBufSize)
406 #else
407 nn::Result ReceiverImpl::Initialize(u16 nodeId, u8 port, void *pRecvBuf, u16 recvBufSize)
408 #endif
409 {
410     if(m_initialized)
411     {
412         return ResultAlreadyInitialized();
413     }
414     else
415     {
416         if(pRecvBuf==NULL)
417         {
418             return ResultNullPointer();
419         }
420 
421         if(recvBufSize==0)
422         {
423             return ResultInvalidSize();
424         }
425 
426 #ifdef _WIN32
427         nn::Result result = HostBase::Initialize(sock);
428 #elif defined(NN_PLATFORM_CTR)
429         nn::Result result = HostBase::Initialize(nodeId, port);
430 #endif
431         if(result.IsFailure())
432         {
433             return result;
434         }
435         else
436         {
437             m_pState     = ReceiverStateClosed::getInstance();
438             m_pNextState = NULL;
439             m_recvBuf.Initialize(pRecvBuf, recvBufSize);
440 
441             clear();
442 
443             m_initialized = true;
444             return ResultSuccess();
445         }
446     }
447 }
448 
449 
Finalize(void)450 void ReceiverImpl::Finalize(void)
451 {
452     if(m_initialized)
453     {
454         m_initialized = false;
455         m_recvBuf.Finalize();
456         HostBase::Finalize();
457     }
458     else
459     {
460         // Do nothing.
461     }
462 }
463 
464 
Wait(void)465 nn::Result ReceiverImpl::Wait(void)
466 {
467     ASSERT(m_initialized);
468 
469     if(GetStatus()==RECEIVER_STATE_CLOSED)
470     {
471         setNextState(ReceiverStateWaiting::getInstance());
472         changeState();
473         return ResultSuccess();
474     }
475     else
476     {
477         return ResultUntimelyFunctionCall();
478     }
479 }
480 
481 
Close(void)482 nn::Result ReceiverImpl::Close(void)
483 {
484     ASSERT(m_initialized);
485 
486     if(GetStatus()==RECEIVER_STATE_FINISHED)
487     {
488         setNextState(ReceiverStateClosed::getInstance());
489         changeState();
490         return ResultSuccess();
491     }
492     else
493     {
494         return ResultUntimelyFunctionCall();
495     }
496 }
497 
498 
Receive(void * pBuf,size_t * recvSize,size_t bufSize)499 nn::Result ReceiverImpl::Receive(void *pBuf, size_t *recvSize, size_t bufSize)
500 {
501     ASSERT(m_initialized);
502 
503     if((pBuf==NULL) || (recvSize==NULL))
504     {
505         return ResultNullPointer();
506     }
507 
508     if(bufSize==0)
509     {
510         return ResultDoNothing();
511     }
512 
513     enum ReceiverState stat = GetStatus();
514     if((stat!=RECEIVER_STATE_OPENED) && (stat!=RECEIVER_STATE_WAITING_FINISHED) && (stat!=RECEIVER_STATE_FINISHED))
515     {
516         return ResultUntimelyFunctionCall();
517     }
518 
519     *recvSize = m_recvBuf.Read(pBuf, bufSize);
520     if(*recvSize > 0)
521     {
522         m_recvBuf.Pop(*recvSize);
523     }
524 
525     // Using Receive as the trigger, notify window remotely.
526     // Since space in the receive window was made, send segment for the purpose of remote notification.
527     // If attempting to send a segment while not in the OPENED state, a state check is performed with the if-statement because there is a possibility that the connection has been interrupted.
528     //
529     if(GetStatus()==RECEIVER_STATE_OPENED)
530     {
531         putAckSegment();
532     }
533 
534     return ResultSuccess();
535 }
536 
537 
Process(void)538 nn::Result ReceiverImpl::Process(void)
539 {
540     ASSERT(m_initialized);
541 
542     // update function for each state.
543     if(m_pState)
544     {
545         m_pState->update(this);
546     }
547 
548     // State Transitions
549     changeState();
550 
551     // Error returned here.
552     // If returned, reset error.
553     nn::Result ret = GetErrorCode();
554     errorHandling(ResultSuccess());
555     return ret;
556 }
557 
558 
GetStatus(void) const559 enum ReceiverState ReceiverImpl::GetStatus(void) const
560 {
561     ASSERT(m_initialized);
562     ASSERTMSG(m_pState!=NULL, "It seems that state is not initialized.\n");
563 
564     return m_pState->getStatus();
565 }
566 
567 
Cancel(void)568 void ReceiverImpl::Cancel(void)
569 {
570     ASSERT(m_initialized);
571 
572     // The cancel process executes immediately without waiting for the Process function.
573 
574     // RST transmission
575     const u32 seq = 0;
576     sendRstSegment(seq);
577 
578     // To Closed state immediately.
579     setNextState(ReceiverStateClosed::getInstance());
580     changeState();
581 }
582 
583 
584 // State Transitions. Do nothing specific if the next state is not set.
changeState(void)585 void ReceiverImpl::changeState(void)
586 {
587     if(m_pNextState)
588     {
589         if(m_pState)
590         {
591             m_pState->finalize(this);
592         }
593         m_pState = m_pNextState;
594         m_pNextState = NULL;
595         m_pState->initialize(this);
596     }
597 }
598 
599 
setNextState(ReceiverStateBase * p)600 void ReceiverImpl::setNextState(ReceiverStateBase *p)
601 {
602     ASSERT(p!=NULL);
603     ASSERT(m_pNextState==NULL);
604 
605     m_pNextState = p;
606 }
607 
608 
putSynAckSegment(u32 ack)609 void ReceiverImpl::putSynAckSegment(u32 ack)
610 {
611     Segment a;
612     a.ClearHeader();
613     a.SetAckNumber(ack);
614     a.SetWindowSize(m_recvBuf.GetRestSize());
615     putSegment(a);
616 }
617 
618 
putAckSegment(void)619 void ReceiverImpl::putAckSegment(void)
620 {
621     Segment a;
622     a.ClearHeader();
623     a.SetAckNumber(m_recvBuf.GetLatestSequenceNumber()+1);
624     a.SetWindowSize(m_recvBuf.GetRestSize());
625     putSegment(a);
626 }
627 
628 
putFinAckSegment(u32 ack)629 void ReceiverImpl::putFinAckSegment(u32 ack)
630 {
631     Segment a;
632     a.ClearHeader();
633     a.SetAckNumber(ack);
634     a.SetWindowSize(m_recvBuf.GetRestSize());
635     putSegment(a);
636 
637     m_finAckSentTime = GetCurrentTimeAsMillisecond();
638 }
639 
640 
isSenderClosed(void) const641 bool ReceiverImpl::isSenderClosed(void) const
642 {
643     ASSERT(m_finAckSentTime!=0);
644 
645 //    LOG("m_finAckSentTime = %lld\n", m_finAckSentTime);
646 //    LOG("Current: %lld\n", GetCurrentTimeAsMillisecond());
647     return GetCurrentTimeAsMillisecond() - m_finAckSentTime > FIN_TIMEOUT;
648 }
649 
650 
clear(void)651 void ReceiverImpl::clear(void)
652 {
653     m_recvBuf.Clear();
654     m_finAckSentTime = 0;
655 }
656 
657 
PrintDebugInfo(void) const658 void ReceiverImpl::PrintDebugInfo(void) const
659 {
660     LOG("-- Receiver debug information --\n");
661     LOG("Current state: %d\n", GetStatus());
662     m_recvBuf.PrintDebugInfo();
663     LOG("\n");
664 }
665 
666 }}} // namespace nn::rdt::CTR
667