1 /*--------------------------------------------------------------------------
2   Project:  HorizonSDK
3   File:     rdt_ReceiverImpl.cpp
4 
5   Copyright 2009 Nintendo.  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   $Date:: 2010-09-14#$
14   $Rev: 25753 $
15   $Author: hiratsu_daisuke $
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 // 「状態」の基底クラス。
35 class ReceiverStateBase{
36 public:
~ReceiverStateBase(void)37     virtual ~ReceiverStateBase(void){}
38 
39     virtual void initialize(ReceiverImpl *pReceiver); // この状態が開始されるときに呼ばれる
40     virtual void finalize  (ReceiverImpl *pReceiver); // この状態が終了されるときに呼ばれる
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 // 以下、派生クラスの実装。
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     //セグメントを受信していれば、ここで処理。
143     Segment seg;
144     if(pReceiver->pullSegment(&seg).IsSuccess())
145     {
146         if(seg.IsRst())
147         {
148             // TCPのRFCによると、LISTEN状態の時に受信したRSTは
149             // 無視すべき、との記述があった。よって、ここでは何もしない。
150         }
151         else if(seg.IsSyn())
152         {
153             // リモートからの正しい接続要求であれば、ACKを返す。
154 
155             // 受信バッファの設定
156             pReceiver->m_recvBuf.SetInitialSequenceNumber(seg.GetSeqNumber());
157 
158             // 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     //セグメントを受信していれば、ここで処理。
184     Segment seg;
185     if(pReceiver->pullSegment(&seg).IsSuccess())
186     {
187         // まずはRSTビットチェック
188         if(seg.IsRst())
189         {
190             pReceiver->setNextState(ReceiverStateClosed::getInstance());
191             pReceiver->errorHandling(ResultResetReceived());
192             return;
193         }
194 
195         // 期待しているシーケンス番号のセグメントが到着しているか?
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                     // データを無事に受信バッファに格納できた。
205                     // 従来の実装ではACKを返していたが、それでは受信側のACKパケットばかりになってしまう。
206                     // そこで、ここでACKを返すのはやめた。
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                 // FINセグメントに対するACK送信
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             // Synに対する応答が届かなかった場合に、SenderはSyn要求を再送することが考えられる。
228             // その場合の対処。
229             if(seg.IsSyn())
230             {
231                 // 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             // 期待していないセグメントだったので、パケロスの可能性が疑われる。
244             // ひとまず今まで受信できた分には速やかにACKを返す。
245             pReceiver->putAckSegment();
246 
247             // ↑このコードを入れると、返って遅くなってしまった。ACKパケットが大量発生したからだろうか…
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     // こちらがFINに対するACKを返し、Finished状態になったとしても、
270     // そのACKが向こうに届いているとは限らない。
271     // ACKが向こうに届いたと判断するためには、ある程度の時間をおき、
272     // 向こうから再送パケットが届かなくなることを確認する必要がある。
273 
274     ASSERT(pReceiver!=NULL);
275 
276     //セグメントを受信していれば、ここで処理。
277     Segment seg;
278     if(pReceiver->pullSegment(&seg).IsSuccess())
279     {
280         // RSTビットチェック
281         if(seg.IsRst())
282         {
283             pReceiver->setNextState(ReceiverStateClosed::getInstance());
284             pReceiver->errorHandling(ResultResetReceived());
285             return;
286         }
287 
288         // FINのセグメントが到着しているか?
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     // タイムアウト判定をしてから、状態遷移。
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     //セグメントを受信していれば、ここで処理。
335     Segment seg;
336     if(pReceiver->pullSegment(&seg).IsSuccess())
337     {
338         // TODO: RSTを含まないセグメントに対しては、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     // CLOSED状態の時に受信した(RSTを含まない)セグメントに対しては、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     // Receiveをトリガーにして、リモートにウィンドウを通知する。
526     // 受信ウィンドウに空きができたので、リモートに通知する目的でセグメントを送信する。
527     // OPENED状態でないときにセグメントを送ろうとすると、接続が断絶している可能性があるので、
528     // if文による状態チェックを行っている。
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()。
543     if(m_pState)
544     {
545         m_pState->update(this);
546     }
547 
548     // 状態遷移
549     changeState();
550 
551     // エラーはここで返る。
552     // 返したら、エラーはリセットする。
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     // キャンセル処理は、Process()関数を待たずに即座に実行させる。
573 
574     // RST送信
575     const u32 seq = 0;
576     sendRstSegment(seq);
577 
578     // 即座にClosed状態へ。
579     setNextState(ReceiverStateClosed::getInstance());
580     changeState();
581 }
582 
583 
584 // 状態遷移。次の状態がセットされていないなら、特に何もしない。
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