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