[PATCH] tools: Add out-of-order statistics to oping

  • From: Dimitri Staessens <dimitri.staessens@xxxxxxxx>
  • To: ouroboros@xxxxxxxxxxxxx
  • Date: Tue, 5 Jun 2018 15:49:19 +0200

This adds out-of-order statistics to the oping tool. A packet is
considered out-of-order if it's sequence number is lower than the
highest sequence number already received.

Signed-off-by: Dimitri Staessens <dimitri.staessens@xxxxxxxx>
---
 src/tools/ochat/ochat          | Bin 0 -> 14616 bytes
 src/tools/ochat/ochat.c        | 211 +++++++++++++++++++++++++++++++++
 src/tools/oping/oping.c        |   1 +
 src/tools/oping/oping_client.c |  18 ++-
 4 files changed, 227 insertions(+), 3 deletions(-)
 create mode 100755 src/tools/ochat/ochat
 create mode 100644 src/tools/ochat/ochat.c

diff --git a/src/tools/ochat/ochat b/src/tools/ochat/ochat
new file mode 100755
index 
0000000000000000000000000000000000000000..289807d9451981e8d41ce23b647f1ff7313a7056
GIT binary patch
literal 14616
zcmeHOdvqMtdB3Z*uyCx0!3KjNo&Zh_VMcyqASPP9JZdaiu_YTq%&^)WNgGzXo1Ix(
zav>Om2pdJghtM83Crw<E14){uv^13Z#Kp$cPTG`Xl2huo^c*)e$tpGna|n)0f$i_R
zbHCN>Xg9R|r~mlcv)}!G-{U^#&VA|rj!m64p^)GZ7PkrFn&x>(ixTWxsUjdPV!gN+
zzaJJ?i;KY5O3ahDcmz@}oL8=y)+sy;ItS1C8V?B4tCSv7&LL4suUgo@$dfP?LX!a5
zQC^Q<Em=@aMwtFc<>R=bY)35Fom6%wl^xTwDq~E!d{j1i`jo#QZHJ5kQ_`i-`<ff4
z_^X#nb{6gPV8N8_J_S3<=l?V`Da9=+y=wKcLgk;SDz0cwCI;56X->xVWFnOt)koK_
z)7PyroV2k@mYe*O?#7;enG&@(S1sjvAs)g=e&^8#-dWPR{m)lCvj2(u9{iI_N4vuB
zl8kh?-5xolg~XheiwV07&tg0W{^PNG+dBU7%!$w4e$`)3z1eX3XKyqBt{8p_^pXma
zlT~o)MjD=A_&$J2e!f!$f3XTa7X_>2=Q`+Xc!D7hppyPSSHW9=Yj}bo3!svpH-TRh
zR0jXcD*De<!9|sF-CITf@hbRW75ql{Z$j(u*EDF%gexR|x!4!LHKiZK?}q6m;zI%h
zSy}kB#2dup3(8<2(BIR!Y<eJ_O*?wr-ifX*ENf^aow6J^nsqHpSY3VHR@~0oLkY*V
zvwhud$#lx@iw-1hPgYqnm`Ejrg&$W8CeypDXe?%DR6J`(;~pBfqse4Crc`F4yRr$_
zrrgEo<y$B0QTWN^TnD*B#$xwavEh5H!Du20AnG_avMRYuHj#1%h2v(Ec1n!cBaZC~
zCovR_xruZN%CXU?g}g<RiQP7-#YQqfDJ50nk!S*Xc0B4vAsBER4+oTri;bJQTHCBu
z#+p)Wm9duUv__5t^y|fVTp%tiWuz4<{UeU}8u1NK9=8@I67@8Ktd#95MDEH2TCzsm
z3Z4Rw>pUJep{XgHP~$h_$JKZ4{8CNI8RvenSM?{xnLn=dY0Rauio*#XK9@nzlRlh%
zk+|T)RTibySs#vqmcn9{AM&k=DrK4v=W&(<%Y8V1D+piV!~NgW^*-GHJ!$db{#VBI
z;i@Xhz3BDf^CjZ_-0s8ugZ14$ywRsW?8CY3Nu2TF{#SL>hx^C5Jw9B0T4gHc_?bF$
zvi5H;(}X#3$gL?JH^*PBJ5tI)aqZ6`DlR*P-^Qgah!H<b^68UBgk}Fie2DntlK(03
z)CALqB>#8BQx}<jTJkRtPfansU-ActrzV)*EBU`5o~nL&kL15gJT>=pM)FS(PhDvG
zZpnX@cxsaAUdca3JT=91i{!sZJaw(<6_S6DcxsYqP4c^mr!F?#1b*e~UHO;qGV?z-
z$4{N@?b|d}`&p!IPSwAKESXaqLdbb>(bpGg;@6E!+a>fVIOsR0YP&$qo6np1*W4>m
zr4K@fs<eJb@#LV<xbz_;A;gX&REsk_TrMEHskQT@o9o|)y?OZku$ez=9xi;s3>`IJ
ze&1aThc_#S^T}Z~e|t6@hMLGVo8ucADb`Q<sW&G#JOQq_=-q{yC~QPQkJj!35ZZAB
zu27D*6eaZ?(}Pf;SpL3u&3x{xneQ)5cDy@&K6LNG@$)sGpF4iO(XBaMceJ*jeC*x3
z;|OV^Ed8jZ!uj`#MTQ<YqoKy)=H#4Z%TatY-*JBBp<@%L{;OC7E6igP1&&T_Sd6MJ
z9Dw!ocOd&4Qh1(z3ftZ<7W2|*{Gc=)TY$uhl-MMxe+fzeYRP^#0CQ^UEZj~?lLIs%
zGxIOyj}^X8vb;>v96u;i9$Ny#6XYoZp=SZj7r~tVs5vQh^M}o;336!WU&y}%{U1XA
zIhnIF?-q-V&(`*!TF1|Z9y-)G(Sf=vxw%hfX2VxX`aguev@|FC&&SQx3uU#qwT0Et
z{IOS!51eU{IX?I!ndA=+fy}DGR{>HE(D6PA?<mzt()QKoxU?6!rRcq{LFK^jN%gfi
zlKRvJ9i%XV?4Twn1y7Mmc7P@;=#gPhv5pkmNpW(*%h6GopTjHbRlzi+J2^o<%sh$C
zlteEPrrb9^^hI*(DIP%7YhV+V{Try|C#Xc@2W7d&2H@s7xG8)O;B%<a;%OJAvWPHv
zh5SzShRn$+f+nS{*ThRGqZ5b5G<bNFJbbpK0K?Zy?v|m|_FbY{E%!~%rCaYggYIEU
zWU`xDX+F2o6tGe&9Y-1R2S1L?nfV{k;1X!0qZ69}QXi+0iAs#<?J9b7qDKm+CTJKt
zu+Lu~PrXCMtKCgS$xHdMj)JsT+A^L$`aBJ@g=uI{9LjA+AC<0HNS~3yPdwo*K_Ly;
zg+KFzR|kbO8WtXtLiaM%<7dzv3)g^uUYadOZ2V8D+#z#(f(l+Yy$upH5HaQ?b)HVy
zg^v~P@!VWpCcIGzd!#VeSU8A!^<MSA|4;JZb2L}!Qu-K9%N@Or4-566TF=pZuU13T
z)HBPx{DV?_74Bzwc}5AJm%`k&CCipN)IT*|ptz^+EU8dgKd<cXujD+ggae-QkCZH>
zbLtKO=RsEXFwywvA7Kz|d{%ZFIn=n<qSMNr<<3J)b}Uq77FFT3)1LFi;+})Do4Iof
zBfwAN!}R;4h)j^BnSX_9@8JqP{hKiU@sYie?U8L=`G1P^NAN9N_VxMlQ>PQ%8p*%c
zl|Q%X`q$(f;_!Rn;-V)TG<@@3cbBgG*T$uL&<0{t{+&(vbM5&zBE^NTn&U@8=FR_>
z`xVVG?%WaiOk_vou84JH@67k`ts`hSnv<wm2+eyb^gGcZ`xY%78;-i#otu06x;FRh
zFbrc}L~{}&nWU{{Y&)yFX`QGh)uNe<F>fAbh6uVIcU&*(`|TUHwN!M(*3yHTi#S#X
zJMFAdvhjGI0is)SDJ|+~(OJqlXiH~4{jIjEF+SsV*iK^pRvy|DP9_;0LpBnQCKX(J
z)YYP?xF(l0UddI4<ciCV8=@2I8auAJY0X<TX|#eeM322oizO3w%Jr+zVoKZE-fxIy
z#tn`!Pn7wLCDTqKHDri3X{b5TF=Qn15l_pAiJX%as6<dzPGoc$xoJzMQZ`misUgaU
zgnap;rCQXrRnBGva^dD>X9i59P_$$cZ8|iJq9@T9LLU~oPBkKQ2QjY-gq}m3vm*33
zILe$?YD+H7LQBH8_M-35<goqiV)1LBYt9vmNzmJVQ!Ks+ngl%sdOzqKjA759+g}HI
z2i}%;&~|*5<Dh>D`aRHv(4`RCy+wpZn?g(G&#l`Vn%hM9Rd@~|osW@%3YGPRxDImC
z-~a1k@hs^!G<7yC{@un8?W)@&K5^x(H>|$y8iGlu9ZwedHVB9`G(B9?R)0|f34<kh
z9M2xe<-DHdJu~u$Aa@{NgZ!85!_6VmAp39O`2x!SWSRVrOY#>XugB>1D|!{#fB3Z;
zvTp};3eO1)AvUOJZD@M5rnO=5m%|+m+SHuZhUH(XH5*nue399(etd3sLrb<{eWYPU
zq+xk$g9bh5w>H$tbuH~}2z>LrH=dkb2p4MLLJeG~feSTop$0D0z=az4;2Pk4Zr<0X
zDFuZf{e}k%+6a_EZR*m}mja)ET;Z{${q!Y@r@0q}D?L)$SEu<D1(v`4elbn_J~gSq
zj)V-$RRnu0GVr-8?;&qg8Rk9l#Y&IP<@^DQOD|}eq&#=(RrWmpqzzOGmwQA!tpLVp
z2aE#e`-I2xF@QX8BnZ<ySsqr!npE=NR`ys_N}lWctl~3Dj%lQn&r$yW--v4OlUHjM
zv#?IdI~Cog=%AuI6@6IIKTz~ZMW0plsG_eZ`U^$RDS8n%xXQ&|)s7q6+HTR7<8=6X
z?IvTDu~J*LV&zRMSFOTvl3%jgSRwQ-4T~iF7|ry*c_<bmws|0zNXCh4cCs-^ad!1V
z!e;5Jsx77P!7hyEL@Jid#qHmkkLFl9HJBKplk|ZE)^CYS)*eiZR>-(MQxv2ReOVeD
zxm)Yj=$V*0f*(rdnr|{tBhB#TjNu4!q`EIzjG1iy@AP$K(?*WF+qGEM9l&{KYO6tf
zr=Pd6VD0Y3)8|9eLT}f)dMvae#X5Q-t(!Wm_Kvo$?#L#qwX5Cg+`Oeb(nrF!EqzvN
z$HuN6#cb{C@9f-aZT1xpYx3qw^-!w+Qo*WeqN4O!+A|GUy(ggLj++}C#Lj>|63xbj
zH+Xj-z`41Uy<x~s+1Uhy(cI`j)UkCOp(ZlrRWT&=A#~u)tAxHCyB*mmD3<^DO{Miz
zG@DKD!ma{Xxmh4Rq=v8wuss%aT>W#oD5;X)n5$>9X*cbTWo(j<BplkzC<oKHt>L(1
zNgL<abm%P4dG$egN-Q<8iIL7yDrrh|5P8TXT|}~WES-((==i#`E8)h5DGhiSP7EYm
z-NE^=9#25YP3%OMC%Z%n*Fsd>9;NeaoGFtLWV`JwDIj@yv>ZoV$KkOjbko?&+G!{C
ztc@h?tU|N4t?!iCqr+%@P`(gUKz^mkaiAccX?g@%9L!>qOV6Zn;>|9j&R8lojFP5v
zj-E@Qp5wYpNA;AE47HoryK$E7>)ReDd$#P=l9zp&I%`Kydxhp!Iu(c6GBAv<G~a{r
z3+Pmw?+=yZVd3%z&nF1uz=yxLJ{afJwSvF1<@iN{zsKeHT*2S1a=cFP_pThjSnzkW
z9G_SE-j?I|x~uO%IX+)#74iDgy|i-u3imaj5EhMMzyEMp8HKUi!uPAn{VWhGc*5Wl
zgmF`Z?-Tf7_`kF??<vO@;=Y*Xhh#h~774yL;1`DJMw9yPmE)I-M=IirXWerlyRhKd
zn%@iIJWHFwX?`+CyeUs*W>9bbQwgWNwHi?`S_0o|nvW5_Cx9<kIL|{ljoT0jVK%i-
zm5cI0p&L)ALVdcx$v@9)NtePNJfRBhLi5^6`F{#H`MFX}DCJ%vu%{JnDxB{IJge|K
z6)yJ<fxV#cN7ckx?im7m2~P<9?YMHl^J<z;R?5#WrTzl(wcv!divHWc>Gn&o-`1f5
zLlyeZhh@cHGOK?!D?HerTcw}b{dOD17Y(!KU_bmM^!@iMWcKi5RlyyJ*NeUCedJ;5
z(}-L`?W_9F$CRUS=xglMM<1)=|65h?XRF}%NqqLW@p2V?y5CtTKl5e&eHm2I%YiTO
zjXyl!|7aEcTYy*cPvd@5h5C<H@pBLGYi4Ihd;$1^n%Vc`zEZ`{ca=WR$JymyN&R}E
zsdkim-Vh!GPWSToy=MKNRq_8u75oO&bEW%zVJ!3(!2cg=nsf~{8R~#j{RGo(1YW6s
zUR4GEohtZ2q(c33t-7ov&j5fOmifov5d2Qj#0FDB-|TSaMxf=6SU6@%VUA&0@w7FR
zOb<kpRvfb~$HFvG#L{$>=i+2*-OcM)S5~4sc?k=1!{`_;+PT>=A!j#MJU22j1`{7A
zFBO)l$`dbS&l%3S@${|~4zqBsD7-Tz@6^bDf@E2}TRQss?yx%hd)ny8(Xx!yYuBtq
zGM!r@-5oUJp^J|e7HU?9sX()Ri?B9s+T4m6{btPAJNm3XIn9S6RZl5L@p3?(>Itj;
zj-E(&SDWxID7LilO+vaq=v`AR$JCv~n3I!L1D|ELGU+a4xdELgmLp|1BZDGLG5t3l
z1LEIu=hM5*nWS5rR@Y`+j*KT#7LM%V>e6KePnB<oT6D!yU9OZ)<+afA8=3)U7H*%a
z)+ycT464MPwB?;LqRwO~sSc@y!27OqQp&!2q%&^TsB57!2(^)eIXqtrmANguy6W9m
z^{U3Z=qe0nYy?wpP&ez*VUEcOdqx<kv}+rY)-FuZhZKk9t|6BJIu_3cal=t(SQzoK
z6#RMA&3Y0XYCCkPRjMh*f-Gw%qhz3BwAwLb`3*XJ76!d)kfr4nSHm7wFV}D!w#<1J
zUZ3_XI1b0r5v(MPp)`Eq$B+ql&S=GB;C&y#J1h(=hb4nEUqh~(ywUCd{!9CGG)7{W
zl7ZJ1OnIM9iKQ;biC&9`_Qu$r*B?wZ$ozr7Z;Y)(#Ba~*6sFg)qM||jcHlU&O>_FZ
zo?*IP+3|iN@7uB49z<yB#`e7KVS2j~(6$`a6WjAX<2GRUB$VuVeZ-XaC!rz(e~*~I
z3lZ82<n(zR#dMWY<ovT9(|aJNy+!7Ey~T8evJd88!D2TeRHtmu>#`D6ikyD1{0}Mn
zR;9=LrA&E$mF(&7F@pAA21a$FwmoOQlj?iP`>;@vA=v(TpniK^4>FZ^29zz4CKYG;
zIC#H3&o7xiNS)Ic*p8vEBI38_{cxti&weof`;|S{Kd(cXew+m=L9Rc=if;$(dEU>o
zj};XSrcdh^%0DN=>sqE668b_g{X>w^l!x8{3cOz6zY_}TGtcxVuxZ4@_I&UDg!(%w
z)+65(m}g4+@6>nLp4Zd-cUUwZr@;M-?YJHP9Wqj3dtP@RUrJWE|L&2}FWWQy1tfm^
z()wKUOdcs&dJ(o``UYUXJ+Gf0(L8<5r^n5dpLtsEkuT0a&u{l>o(8Amab8*+C;AQ^
zN<Uamw&!&g=~5tF3QWU@RI)#!Nj33Qpu@49pK{;xEWF>$GLN2A?;m}KXe{LN@c2vb
i7nj|$@P2!BkFE{~IbGJJ<w-zAipEuiED9I|Sn=P&!QOrV

literal 0
HcmV?d00001

diff --git a/src/tools/ochat/ochat.c b/src/tools/ochat/ochat.c
new file mode 100644
index 0000000..3dc5f95
--- /dev/null
+++ b/src/tools/ochat/ochat.c
@@ -0,0 +1,211 @@
+/*
+ * Ouroboros - Copyright (C) 2016 - 2018
+ *
+ * A simple chat application
+ *
+ *    Dimitri Staessens <dimitri.staessens@xxxxxxxx>
+ *    Sander Vrijders   <sander.vrijders@xxxxxxxx>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define _POSIX_C_SOURCE 199309L
+
+#include <ouroboros/dev.h>
+#include <ouroboros/fqueue.h>
+#include <ouroboros/fccntl.h>
+
+#include <assert.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <pthread.h>
+
+#define BUF_SIZE 1024
+
+volatile bool stop;
+fset_t *      set;
+fqueue_t *    fq;
+
+static void shutdown(int signo, siginfo_t * info, void * c)
+{
+        (void) info;
+        (void) c;
+
+        switch(signo) {
+        case SIGINT:
+        case SIGTERM:
+        case SIGHUP:
+                stop = true;
+        default:
+                return;
+        }
+}
+
+static void usage(void)
+{
+        printf("Usage: ochat [OPTION]...\n"
+               "A simple peer-to-peer chat app.\n\n"
+               "      --dst                 The name of the server.\n"
+               "      --server              Run as a server.\n"
+               "      --username            Set username.\n"
+               "      --help                Display this help text and 
exit\n");
+}
+
+static void * accept_thr(void * o)
+{
+        while (!stop) {
+                fd = flow_accept(NULL, NULL);
+                if (fd < 0) {
+                        printf("Failed to accept flow.\n");
+                        break;
+                }
+
+                printf("New client.\n");
+
+}
+
+static int server_main(void)
+{
+        int     fd = 0;
+        char    buf[BUF_SIZE];
+        ssize_t count = 0;
+
+        printf("ochat server started.\n");
+
+
+                count = flow_read(fd, &buf, BUF_SIZE);
+                if (count < 0) {
+                        printf("Failed to read SDU.\n");
+                        flow_dealloc(fd);
+                        continue;
+                }
+
+                printf("%.*s.\n", (int) count, buf);
+        }
+
+        flow_dealloc(fd);
+
+        printf("ochat server closing.");
+
+        return 0;
+}
+
+static int client_main(const char * usr,
+                       const char * dst)
+{
+        int              fd       = 0;
+        char             buf[BUF_SIZE];
+        char *           message  = "Client says hi!";
+        ssize_t          count    = 0;
+
+        assert(usr);
+        assert(dst);
+
+        printf("username is %s.\n", usr);
+        printf("Connecting to %s.\n", dst);
+
+        if (dst != NULL) {
+                fd = flow_alloc(dst, NULL, NULL);
+                if (fd < 0) {
+                        printf("Failed to allocate flow.\n");
+                        return -1;
+                }
+        }
+
+        while (!stop) {
+                if (flow_write(fd, message, strlen(message) + 1) < 0) {
+                        printf("Failed to write SDU.\n");
+                        flow_dealloc(fd);
+                        return -1;
+                }
+        }
+
+        if (dst != NULL)
+                flow_dealloc(fd);
+
+}
+
+int main(int argc, char ** argv)
+{
+        bool             stop     = false;
+        char *           username = NULL;
+        char *           dst      = NULL;
+        struct sigaction sig_act;
+        bool             server = false;
+
+        memset(&sig_act, 0, sizeof sig_act);
+        sig_act.sa_sigaction = &shutdown;
+        sig_act.sa_flags = 0;
+
+        if (sigaction(SIGINT,  &sig_act, NULL) ||
+            sigaction(SIGTERM, &sig_act, NULL) ||
+            sigaction(SIGHUP,  &sig_act, NULL) ||
+            sigaction(SIGPIPE, &sig_act, NULL)) {
+                printf("Failed to install sighandler.\n");
+                exit(EXIT_FAILURE);
+        }
+
+        argc--;
+        argv++;
+        while (argc > 0) {
+                if (strcmp(*argv, "-h") == 0 ||
+                    strcmp(*argv, "--help") == 0) {
+                        usage();
+                        exit(EXIT_SUCCESS);
+                } else if (strcmp(*argv, "-s") == 0 ||
+                           strcmp(*argv, "--server") == 0) {
+                        server = true;
+                } else if (strcmp(*argv, "-u") == 0 ||
+                           strcmp(*argv, "--username") == 0) {
+                        username = *(argv + 1);
+                        argc--;
+                        argv++;
+                } else if (strcmp(*argv, "-d") == 0 ||
+                           strcmp(*argv, "--dst") == 0) {
+                        dst = *(argv + 1);
+                        argc--;
+                        argv++;
+                }
+                argc--;
+                argv++;
+        }
+
+        if (!server && (username == NULL || dst == NULL)) {
+                usage();
+                exit(EXIT_FAILURE);
+        }
+
+        if (server)
+                return server_main();
+        else
+                return client_main(username, dst);
+}
diff --git a/src/tools/oping/oping.c b/src/tools/oping/oping.c
index 4057874..99f1e9d 100644
--- a/src/tools/oping/oping.c
+++ b/src/tools/oping/oping.c
@@ -75,6 +75,7 @@ struct c {
         /* stats */
         uint32_t sent;
         uint32_t rcvd;
+        size_t   ooo;
 
         double rtt_min;
         double rtt_max;
diff --git a/src/tools/oping/oping_client.c b/src/tools/oping/oping_client.c
index e48b01c..1d64e01 100644
--- a/src/tools/oping/oping_client.c
+++ b/src/tools/oping/oping_client.c
@@ -65,10 +65,13 @@ void * reader(void * o)
         int                msg_len = 0;
         double             ms      = 0;
         double             d       = 0;
+        uint32_t           exp_id  = 0;
 
         fccntl(fd, FLOWSRCVTIMEO, &timeout);
 
         while (!stop && client.rcvd != client.count) {
+                uint32_t id;
+
                 msg_len = flow_read(fd, buf, OPING_BUF_SIZE);
                 if (msg_len == -ETIMEDOUT) {
                         printf("Server timed out.\n");
@@ -84,7 +87,8 @@ void * reader(void * o)
                         continue;
                 }
 
-                if ((uint32_t) ntohl(msg->id) >= client.count) {
+                id = (uint32_t) ntohl(msg->id);
+                if (id >= client.count) {
                         printf("Invalid id.\n");
                         continue;
                 }
@@ -106,11 +110,15 @@ void * reader(void * o)
                                (size_t) rtc.tv_nsec / 1000);
                 }
 
-                printf("%d bytes from %s: seq=%d time=%.3f ms\n",
+                if (id < exp_id)
+                        ++client.ooo;
+
+                printf("%d bytes from %s: seq=%d time=%.3f ms%s\n",
                        msg_len,
                        client.s_apn,
                        ntohl(msg->id),
-                       ms);
+                       ms,
+                       id < exp_id ? " [out-of-order]" : "");
 
                 if (ms < client.rtt_min)
                         client.rtt_min = ms;
@@ -120,6 +128,9 @@ void * reader(void * o)
                 d = (ms - client.rtt_avg);
                 client.rtt_avg += d / client.rcvd;
                 client.rtt_m2 += d * (ms - client.rtt_avg);
+
+                if (id >= exp_id)
+                        exp_id = id + 1;
         }
 
         return (void *) 0;
@@ -241,6 +252,7 @@ static int client_main(void)
         printf("--- %s ping statistics ---\n", client.s_apn);
         printf("%d SDUs transmitted, ", client.sent);
         printf("%d received, ", client.rcvd);
+        printf("%zd out-of-order, ", client.ooo);
         printf("%.0lf%% packet loss, ", client.sent == 0 ? 0 :
                ceil(100 - (100 * (client.rcvd / (float) client.sent))));
         printf("time: %.3f ms\n", ts_diff_us(&tic, &toc) / 1000.0);
-- 
2.17.1


Other related posts: