From 8a0cd931ca5edf61e0afaeb535e2b00ccbc71e0d Mon Sep 17 00:00:00 2001 From: Pedro Berrocal Date: Tue, 7 Aug 2018 12:29:33 +0200 Subject: [PATCH] MWMap class --- .gitignore | 10 ++ README.md | 5 + certs/README.md | 49 +++++++++ certs/cacert.der | Bin 0 -> 973 bytes certs/cacert.jks | Bin 0 -> 1032 bytes certs/cacert.pem | 23 ++++ certs/client.jks | Bin 0 -> 3519 bytes certs/client.p12 | Bin 0 -> 2814 bytes certs/makedemocerts.py | 126 ++++++++++++++++++++++ certs/server.jks | Bin 0 -> 3553 bytes certs/server.p12 | Bin 0 -> 2854 bytes include/MWMap.h | 38 +++++++ include/MWSessionI.h | 28 +++++ include/MWSessionManagerI.h | 25 +++++ src/MW.ice | 77 +++++++++++++ src/MWMap.cpp | 99 +++++++++++++++++ src/MWServer.cpp | 84 +++++++++++++++ src/MWSession.ice | 113 +++++++++++++++++++ src/MWSessionI.cpp | 210 ++++++++++++++++++++++++++++++++++++ src/MWSessionManagerI.cpp | 66 ++++++++++++ src/Makefile | 29 +++++ src/Printer.ice | 7 -- src/Server.cpp | 38 ------- src/config.glacier2router | 84 +++++++++++++++ src/config.mwserver | 44 ++++++++ 25 files changed, 1110 insertions(+), 45 deletions(-) create mode 100644 .gitignore create mode 100644 certs/README.md create mode 100644 certs/cacert.der create mode 100644 certs/cacert.jks create mode 100644 certs/cacert.pem create mode 100644 certs/client.jks create mode 100644 certs/client.p12 create mode 100755 certs/makedemocerts.py create mode 100644 certs/server.jks create mode 100644 certs/server.p12 create mode 100644 include/MWMap.h create mode 100644 include/MWSessionI.h create mode 100644 include/MWSessionManagerI.h create mode 100644 src/MW.ice create mode 100644 src/MWMap.cpp create mode 100644 src/MWServer.cpp create mode 100644 src/MWSession.ice create mode 100644 src/MWSessionI.cpp create mode 100644 src/MWSessionManagerI.cpp create mode 100644 src/Makefile delete mode 100644 src/Printer.ice delete mode 100644 src/Server.cpp create mode 100644 src/config.glacier2router create mode 100644 src/config.mwserver diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..29e9e3f --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +*~ +#* +*# +/src/obj +/src/MW.cpp +/include/MW.h +/src/MWSession.cpp +/include/MWSession.h +/src/BuiltinSequences.cpp +/include/BuiltinSequences.h \ No newline at end of file diff --git a/README.md b/README.md index 0001253..efa6e7a 100644 --- a/README.md +++ b/README.md @@ -31,3 +31,8 @@ c++ -std=c++11 -pthread -I. -DICE_CPP11_MAPPING -c Printer.cpp Server.cpp ``` c++ -pthread -o server Printer.o Server.o -lIce++11 ``` + +# Develpment +## TODO + - User Object + - ... \ No newline at end of file diff --git a/certs/README.md b/certs/README.md new file mode 100644 index 0000000..8d303b6 --- /dev/null +++ b/certs/README.md @@ -0,0 +1,49 @@ +# Demo Certificates + +This directory contains certificates used by the clients and servers in our +sample programs. These certificates are for testing purposes only and should +**never** be used in a production environment. + +As provided, the server certificates use `127.0.0.1` for the Common Name, the +IP address and DNS name. This works fine when you run the client and server on +the same host. However, if you want to run them on separate hosts, you may need +to regenerate the certificates. (This is especially true for the JavaScript +examples.) + +We've included the Python script `makedemocerts.py` to simplify this task. + +## Prerequisites + +You'll need Python to run the script. The script also depends on a utility +package from a separate [ZeroC repository][1]. You can install this package as +follows: + +``` +pip install zeroc-icecertutils +``` + +## Usage + +Running the script with `-h` displays the following usage information: + +``` +Usage: certs/makedemocerts.py [options] + +Options: +-h Show this message. +-d | --debug Debugging output. +--ip The IP address for the server certificate. +--dns The DNS name for the server certificate. +--use-dns Use the DNS name for the server certificate common + name (default is to use the IP address). +``` + +The `--ip`, `--dns`, and `--use-dns` options affect the generation of the server +certificate. Without any arguments, the script prompts for the value of the IP +address and DNS name. + +You can specify an alternate IP address using `--ip` and an alternate DNS name +using `--dns`. The `--use-dns` flag forces the script to use the DNS name as +the server's Common Name instead of the IP address. + +[1]: https://github.com/zeroc-ice/icecertutils diff --git a/certs/cacert.der b/certs/cacert.der new file mode 100644 index 0000000000000000000000000000000000000000..e4e6af2936cf6a15a5d7231898065182af2d56e7 GIT binary patch literal 973 zcmXqLVm@im#I$h%GZP~d6Gvk2jeV`lp7I*-vT1BDGm41_>DE*|cv)S`T69R<(4WIaOx13r)_ zI}f{8X+dU5Y7tC?gNNNMC%-5&CDD-EfD@#KO_(V(*ihC$8g4%)qZnUiURu6G70|?F zz2y8{137VCLkj~719Jm2LrYVGC~;mRV<6WI${l2`ZDLeH4o*f^2IeM4eg=akMlPl% zMn;Au_wxMS*-OT@RLol5zBIu0lV3<#jfhaGWZ{f0d~2Egjs$OLI$?bCp39y)^B2zF z&ewIXs=j=q?Uqy5&5{CplEv=5-R6BrY(Zo8f-aLqvK{jujBuI<`ypRooA zZt`WcTDbG*l?zj!b_qM|@I5iV@Bv3v^DN6gg%wqwL^GGwn<#f?uBo_xIwgOzK*WjH z)APLTN~8b2-Mat6<`eCUa%w*KOzm79&Jda(dSUnWIjULrZ8l0d=)bvTaw4*JiouMY z_ngP#-tL}uzcW=6*U2C^U?ABz}^2$#3aHjl`z z(tF?RtY=!Sp8aq_YZh{l0#hh3NEsPg67H;WT=q^PI!3`sJG@QrMaA}_wbN$`ZZY4l zD?VX&`afCyD9J_bmY-rX82nAnd|ug{fJ7E25c zG*>ZpjF9Lpl$vq)y1-7xSJHCPbvo0E(gpkqCyNxxNw1sdy7v7tBh}+qWG-$#)0n`! z!Tx%6Q9<^r4L{G#&%36+uA*uOn_k^{8_As?n52L2W)5QQzO;JAzpvVFzn3++K3}ts l+v3qL9>ECt$+0pLCPv4d*_U0ekqTX79vS8#6Z2I}6960HUpD{% literal 0 HcmV?d00001 diff --git a/certs/cacert.jks b/certs/cacert.jks new file mode 100644 index 0000000000000000000000000000000000000000..5141f34b3363add10011974559554523ba6dbaaf GIT binary patch literal 1032 zcmezO_TO6u1_mY|W(3nr$%#N_sxa5;tqiOYdZq@J3=GU?4Vsuw8Z$0c32E1&XT5TR}-+37sxmg(u8oLce4TRa4Ls^)4cs!F+6B+Aai?p0clS&~`=6XD=tcgx8y z%1lW#Is0QdT1(R4Q3GV+-F}X1^oB8=6iS-@NCt=g$0v^SASL-K(lE-)Ot#)OE9@z@B8W zdvCXSA6H$y_53O8iksW6X9`?1ka~aYxrb}J_SyBfy?xJ}clvYuy|e#n&Ab1ruUqsmhW-*?KYgb@V``v_@PX((Io0t@%!~|- zi}ek34S0YlKvtNA)qt6i@xOsAh{wkw#v;PyEwjxdva9soH#_T@R;y<}oY0zu9HhV$ z3Jg+4hL(gos~nfTlZcK{aMBKM(|b{|y=d+9nSxu)_v?yJ*q#1QRzFH|QM=`**bD~0 z*d-#`Csy_;EML{SYFp>uSAjDF?m8$puU_)ecF)23&8s*+x3|oHu*uKh=)A(|mlfV| zvP_(*taJ7Z$EnKn`ASPSr%qN|b4t2z!qV$=<&?z|g9FV~j2$B+dJCmy9KJ5Flkt_b zTy&kzw4!tYzrx8PMRL;X=DDtYzsyMW_!XIpo6j^R@NTfbUR_j>{c6L{bMy1AsjsW3 z+QFt*ciu*F=LaU~-@BQESi3K+p7HOi_S^4eO|H+^?Blk0^ovI@LVj|rjD(5NacA~r omusX#*O*6!dC0_k71NAaGPn6+RO*iH9LIEjTJ&Dg>XUB+0Ib4sy#N3J literal 0 HcmV?d00001 diff --git a/certs/cacert.pem b/certs/cacert.pem new file mode 100644 index 0000000..f3d8528 --- /dev/null +++ b/certs/cacert.pem @@ -0,0 +1,23 @@ +-----BEGIN CERTIFICATE----- +MIIDyTCCArGgAwIBAgIIYY3YvoWm5Q0wDQYJKoZIhvcNAQELBQAwgYsxFTATBgNV +BAMMDEljZSBEZW1vcyBDQTEMMAoGA1UECwwDSWNlMRQwEgYDVQQKDAtaZXJvQywg +SW5jLjEQMA4GA1UEBwwHSnVwaXRlcjEQMA4GA1UECAwHRmxvcmlkYTELMAkGA1UE +BhMCVVMxHTAbBgkqhkiG9w0BCQEWDmluZm9AemVyb2MuY29tMB4XDTE4MDgwNzA2 +MTk1MFoXDTIzMDgwNjA2MTk1MFowgYsxFTATBgNVBAMMDEljZSBEZW1vcyBDQTEM +MAoGA1UECwwDSWNlMRQwEgYDVQQKDAtaZXJvQywgSW5jLjEQMA4GA1UEBwwHSnVw +aXRlcjEQMA4GA1UECAwHRmxvcmlkYTELMAkGA1UEBhMCVVMxHTAbBgkqhkiG9w0B +CQEWDmluZm9AemVyb2MuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEApN5uTu4/GV2EeJqnh6VQPfJOVHZ8FBJ1GXGYtA6tA07EU7CCyDPZ3kS83J+h +n7cOit56f3exPbTK1zZiUYxjFt7ttkvHJau1z8o7eNm212kQ1jAa78bnSEWHK+3m +BVARsk0BOqG5xdTQleWKE0C4TcifceAIeoOaOY4gqHryFWmmfzQjiWmseN/LZG+z +EFjI65duSz51W/3ttb/Qs8iHomx88EyViatXAFVvVdC7t5wlat88sRpAL+zaNMhZ +fZQwmIzvCcZe7buWwEelUB7q5wFMoXhoIibZLDsOjY7nQ7lPCP3cv9V87v+r1ziM +AVX6F6+XuS8BZVFEE8BbvGx7XwIDAQABoy8wLTAMBgNVHRMEBTADAQH/MB0GA1Ud +DgQWBBQKSxy2SFmKdd72PjuZOqub4ZCFajANBgkqhkiG9w0BAQsFAAOCAQEAhGDc +qkGm7hhbXCBCK1eGLuh4t3Ktl5kRtDe/LReQu2f+HS9aGaKHOfJdaABOXaQUK8ip +jiCnqoWqton96lGZUN1AI4OrpPE9vMF/s6oJ84eEn+CyTjDFnnGX0yDuCQSRmSMs +zcwIynlnnyKls2WTJqzKG46QpdedHiMWYVNRNyQzQVgYjXEamMPXELkB6hseW34s +lnJnEE5xkxRyHhuunkWt76YyJcfUHNGzzIFgDbA/13tycGvqsPnOn27WJ654ergG +Ln7PPBm58AIb+7sDUgWL0quY/vUr7fd2gkXnrL4LOOL6DBFYH5NdHBg0MsdDB6bT +fBpVrDdZVkgcXPUWKQ== +-----END CERTIFICATE----- diff --git a/certs/client.jks b/certs/client.jks new file mode 100644 index 0000000000000000000000000000000000000000..77896d67db96bc6653c21815e49eff85da19fd48 GIT binary patch literal 3519 zcmdUxc|6o>7r^H?i|kAWBTKHeGWZR$Wl2J1->zL4k}#tQ&6SH8B4x?gm+WNAHrXP> zbu$_j*|~O=k}Z;(YkBp)z4vqfxS!Aa=li~YJb#??JfHJC=RD_p&)HwuUx7d%(C-U? zu;BcByzqe#2;jxXUhNHmAfO-xz7KM=KPoC06ERsB5cc$yq-woic% zR_OSSrt)0WWzWOOv=eS@u0b=-;?Yb$G+a41m;U<4@OZ#1Y049%i-hE;OVAil~yirYP6yC?>49KCxc2V zD(NSw?_{Vi#?0o#era;heek4D_)T{0Cgk0Sb}1%J(H#{uGEnzt+rfX zJ7Eu!A>5m)qxX3TbMEqSQ@yt91DIOr_ok@aS@U@*vnj!=2OqDUc%qdZcISEiAR_ge zmh%Qr^_+f}e2Izk>2eC{t1I#NSNSa68(^~IsfGO;N(b}PC1L!65I=>6{ISIy%4JP1 zyQ78`HvDMbu5E&5%B#02PL}9BQdf>H<%yd8Cvw`| zeIY?7`-0f=Hx3GRw{=167u`jlnl*3Zk`ci`=DEaE>Z&uE&> zVuth1yYra7hRmcpQ&;+LPCXLjB}Q5}K8#JuaozlYmk>4~vG89yIM;372KUuWz^N=~ zg$or=3dkZ^*6pU+)14h%iB39ehL}`$8S6Kzb*i2jt*$xppW#L|Fb;|mVy~}mQH-qW zpN-t(0zbw$aiDp9-fM#f_wMZ&6`r)48W%)!fSvOU@|B}lyK%ey%`a^|BfnDxrvRZK z$%I%pt(lvi{dj@&;JSdK-n%L0u~XAZ9*J?2)Rk&H{roD~icsetK2aYQ?OV=N4M{mI znn6z*3Fff78M%o2l+qY@CN+#3?S~{|o#U4Ryo*x8<{7$vTu~7JjT5k%AWqMxa~VS> z$V3mwkW{uW?LD9r4|Wu?Hz*!gQ`XAJ%~NWqQSG0Nn0!i?#IIE@8~$di6HBCH zUgn0{%gQWgloC5Zu6xg6R3TxqrKZ+B(yJl;m zNQB_YN@O3?&7l7EjBpD%Y{~YrrwTQG+Y2XB&^uwyY-V!3(A5$zXT;}TA%5mPvhPTx z=vrH@4aKm>$mH2TFndPF4um1oVZGCEj&8IT8;qgM^=oX>ANSpnVFs>uUeucz z zL7Q-}XQaXVr(9Q`wJ*0vP3C(C&i6t9VFnrJ~zRedCpr?L3m_K@+o|Xa(c4@Az=42(c)DXbK(=pZSool})>u(c_|N;<00C|v{1w94kVA_& z1suU26cgmas)OpF8mNlZI1M@qaw#bvimKm5kbE14y6D9r2DjNtQ3i9(>PLATG)Er5q2)t->{jfLnc{u0vY6yhMD;^wc(N^ zvmuH-tI&haTqIeE?_#6!E9&LB%z@@`iy8Ta?AvK%a3|VxYR&)7U`DK+$=p|oOKd(E zVaKHRW7*w?3tlf3GsyY}Rz{=sbDTaQ*jKmS(x5GGw`z>`iUOO+ed!KYq_Ro(U$p(^ zu3M7*IxoOC?9>)EYU`{7U1s{zFPj>quMv|yek#&{oUW`rV}`zHn^}Tf-ZR)-xRk*5 zh)VI_((&D|^_Lb1LGwR)M~?tgxqeZN<(m*tJ2On1(pR~-HC5iFrT25d_&`=;!-oQ^ zu#Tn~-d~*@_@OWW0u+%yf#g+C^zgexx#0qERNywvrN-x@tE^QZBUpRKMTH3~2Fdhq z`;u^S6G(m>fnqlnX}sWYH)#5c&Y4Wj%IvxOx33kDlZwd+|68d_VRermYrkFkmJ8(g z<^T^I4uc|Q|C$wt<#m`90OV#ADeUwpZJaH|tfsSm@QzS-=S2D3wKC*PP0d|SipTkgSvSU5xOj|@ zMpEoh`OBh4JB5^KGY1j<5Ts&RFtF6SP7UbyZV|I)NyuumZhmljct2=}VpH*%v{8=g zklE(;C68FX+8rRaD!>_Jt?Vrov6W@AX6==cE!CwrCj~;dGhYXpnBKst|Iyc%;}MV{ z{jOCrP%rRo%Lw|&pk@5j#2%3@y~${{e`0OzHe~CkeZMh#2xJY2D1528-#NeAm;}YX z-;QVwiqsUKa(!WRuK#mvW5K!OyoldNwnu4yf(rKX5K_-U3bgJ!sQwJ=|2L@qr?C2; za8*2wH(S*ea)}~kJ&Y-_(B3e!2@XXa4HCMZ@tFG&%lXcv>!7^RXr@@a01gSjm8Y=%7#AX8Pa&;s1NT5cx$9vOky#oE;$X;0 z-cRd^DfA0nH%X1Hw1e0ZZ2McAa-^@#Xw@A%tGGO&(&O-R3YZbM#@6k+(wf#`RAM2v zv*>9XE?2bZ8Ih+ zZ?@hHe3pAXeNcRr4W5)KiFx^gmHCr*oWb}cUq=37%rJ9too;^DL z`mv0zQQj6{Nm$G&43kFm<~6&Xj3SB&SLYf$S}RqOW(& literal 0 HcmV?d00001 diff --git a/certs/client.p12 b/certs/client.p12 new file mode 100644 index 0000000000000000000000000000000000000000..04c1c78eeac78e17a9237b9d72d5149d68c9da67 GIT binary patch literal 2814 zcmZY9c{CJ^8V2wgnK70qdt=|SGuA=KRuQA@3fUWjtRp*_$~t5Zg$eUz>>5c!_I*iX z$yTAX}mSDo-2>KsObD3;8d?AcCJ`sSWKiIOG!=?r8CpQh=YDJL1*5N<*% z21{6m+L(XdyHoOMtGd;Rm*eGb!BR)xY)!J`#mI3VrXv^r5p4T_ujgExnT6rcj9Vs` zOzyfyL5DIaClxbqyL7VN@ocRoi-jyz>o8-!Q;x^q_0ZSv{92NIM5S6DVFDRYIG$^% z0Kn2*4GM|}vbn_IZpqTi3+S3{g?4F13)+t%!uG>ooe&DuU$LuexrK};$Xn>E8OO97 zlm#xS5u$s#3w`Ne&$Dbc%%G7gfo~oDcD}eU)JEDd&#R3)_kIIs#7SfJ@9!O3C+P|I zqblnqDy`@zwmaZQMF~@5V3BE%w2l7qtKKWM;6AJDih!+9RT4ITXZb2a=%U+T9nU@1 zp>WF4P0rZSP!m0lndQCIa*Apd5PN$HIT9LU&X`E&MM~fgTMed}$MHfC#wpus#l{;# z@8Zg3qxyTFbp@G6(Fzbxpq!Eo5uKgb8Ykn+{MqlTos<)0WO6JSt~`dvUV9__t&rSQ z$-hWcs^}YuHHL8$e_zEVzE5S>4rRW4xEL6t%%!wOUUwcA077DF!g3~5X{iszFMXcR?F@H7iBO!VxM>&S7KjF>$i)$MUA^>EU(ifHC+5|nsT<*N_6=pI3Tl4@AItPGfeqjrL`sC z{zSx`gy$D~NDyM9>bINO_D8$Y-PntJ<$T8Mw7d8+3NfDt?m1GsO#WFaPD8M(Xh@K3 ztj-w@{XJ(MuEZYKDV#(bI^WR$3XGqBpABp(bJgQt=fhj3MIX1CJ6}U;D(MxQG$)UM z`sKufeLpIFyu2_ZU|Q~x4}Nf zyar3h#&O#Y#{e-i@_x+9QT*x=liP$>VFG*#k@CPMXqpRc(~hsEM%Q2ttxu)+*5g1UqgT8(_xJnOACW zM)%s3+-hd7H0`K8`9WpXYoj`0-T3_C$1%z*HkkS}mvb;5{12Gtl-{AnfDHc@_WX3g z^#9?L4oHQ=P_M%<)Ia}URrR#ns2i+GPJgRPjiK%qN{Z<~Ov_<2UfBIP;bc1qMEvqO0>c1-Ya>3b6%8@Rau`AefJU_4{Xvd&KXEHGAM?W(7_)(IvDscddv z>X@#z63Q)4R`VBWmBsJ~wIjGbk?o5EWg4`f{kf)V)2n}ROVdS>L72sVrBL*zt=S!# zO_vR_aYUVDN^K*(=-A~K2TXiEmThd=58;=_s+YLt((j`APTrYQa{h!W`Mh7$2iJW_ z*KjgX02KvnE)H5Lv&j1r-M9+oLc+TRfz~WK?%1GUtyA=8j1p0ni9y%H;`X1=SU)*3 z^HPf2&SHNS)bp#0)Nsm-+XEbl|Fpaum9LL7t&;XDGl4&kEXMmWnM&3!W=PR51m+(( zIjXCAkkaLG_2!y}HKnKn1I7$mlSv*r#syCdecF*KJyYa0!y<=YADRN+j0a1(B5hin zRhZk95C!IPzNiVFsTOEC$$fWz7qEBzC&HrUge_b^ihb1 zW|oABsvz8y?SMxZ}E|C@2e9d47DIRDb(n5{4F;?Tr_ue?1viFx?yHQHfF$0CRUTQ1{B?F`(|_BeLgbw!bp@eTwGG4 zJ!AH3gpkCjd~E}L$>d&2m;Hxw%`_qb{1(G~k(a~L)eK5asMPp*Fy_a{mS5D>X8_O7 zy{s;_iPN=GQRH0v@s~ce62AQk_D2}Y;TiNe&?)%ow-GZ7it@UQ%9-YcE=u2&Y5&p- zX6y_kD?`Mc(E}R%@~-JP_IvJZq0k4)yKh$OjRhWND=iiE#9v$vl%SrQUTiKgLro@2 zFOsUlXJ2&4y|!l4Npxh*@k`iZ#_1weEA~nsW5;7vuY=JDc zYN%Z~9T?Ytb);pLW8`H3I0HNZD1a-#3xI|R{Zq2Zu~W0Y%jxo|9bfPLeyVZ2ewTyD zP;JBmlZFYvXu%*!#tT$X5P+IB-m*2J%L>yL`nfTHIY*ozm|5&a4Utc5t5VcnSpFA` CX+|{w literal 0 HcmV?d00001 diff --git a/certs/makedemocerts.py b/certs/makedemocerts.py new file mode 100755 index 0000000..4a42b35 --- /dev/null +++ b/certs/makedemocerts.py @@ -0,0 +1,126 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +# +# ********************************************************************** + +import os, sys, socket, getopt + +try: + import IceCertUtils +except Exception as ex: + print("couldn't load IceCertUtils, did you install the `zeroc-icecertutils'\n" + "package from the Python package repository?\nerror: " + str(ex)) + sys.exit(1) + +def usage(): + print("Usage: " + sys.argv[0] + " [options]") + print("") + print("Options:") + print("-h Show this message.") + print("-d | --debug Debugging output.") + print("--ip The IP address for the server certificate.") + print("--dns The DNS name for the server certificate.") + print("--use-dns Use the DNS name for the server certificate common") + print(" name (default is to use the IP address)." ) + sys.exit(1) + +# +# Check arguments +# +debug = False +ip = None +dns = None +usedns = False +impl = "" +try: + opts, args = getopt.getopt(sys.argv[1:], "hd", ["help", "debug", "ip=", "dns=","use-dns","impl="]) +except getopt.GetoptError as e: + print("Error %s " % e) + usage() + sys.exit(1) + +for (o, a) in opts: + if o == "-h" or o == "--help": + usage() + sys.exit(0) + elif o == "-d" or o == "--debug": + debug = True + elif o == "--ip": + ip = a + elif o == "--dns": + dns = a + elif o == "--use-dns": + usedns = True + elif o == "--impl": + impl = a + +def request(question, newvalue, value): + while True: + sys.stdout.write(question) + sys.stdout.flush() + input = sys.stdin.readline().strip() + if input == 'n': + sys.stdout.write(newvalue) + sys.stdout.flush() + return sys.stdin.readline().strip() + else: + return value + +# +# Change to the directory where the certs files are stored +# +os.chdir(os.path.dirname(os.path.abspath(__file__))) + +if not ip: + try: + ip = socket.gethostbyname(socket.gethostname()) + except: + ip = "127.0.0.1" + ip = request("The IP address used for the server certificate will be: " + ip + "\n" + "Do you want to keep this IP address? (y/n) [y]", "IP : ", ip) + +if not dns: + dns = "localhost" + dns = request("The DNS name used for the server certificate will be: " + dns + "\n" + "Do you want to keep this DNS name? (y/n) [y]", "DNS : ", dns) + +CertificateFactory = vars(IceCertUtils)[impl + "CertificateFactory"] +factory = CertificateFactory(debug=debug, cn="Ice Demos CA") + +# +# CA certificate +# +factory.getCA().save("cacert.pem").save("cacert.der") + +# Client certificate +client = factory.create("client") +client.save("client.p12") + +# Server certificate +server = factory.create("server", cn = (dns if usedns else ip), ip=ip, dns=dns) +server.save("server.p12") + +try: + factory.getCA().save("cacert.pem").save("cacert.jks") # Used by the Database/library demo + server.save("server.jks", caalias="cacert") + client.save("client.jks", caalias="cacert") + + # Don't try to generate the BKS if the JKS generation fails + try: + server.save("server.bks", caalias="cacert") + client.save("client.bks", caalias="cacert") + except Exception as ex: + for f in ["server.bks", "client.bks"]: + if os.path.exists(f): os.remove(f) + print("warning: couldn't generate BKS certificates for Android applications:\n" + str(ex)) + print("Please fix this issue if you want to run the Android demos.") + +except Exception as ex: + for f in ["server.jks", "client.jks"]: + if os.path.exists(f): os.remove(f) + print("warning: couldn't generate JKS certificates for Java applications:\n" + str(ex)) + print("Please fix this issue if you want to run the Java demos.") + +factory.destroy() diff --git a/certs/server.jks b/certs/server.jks new file mode 100644 index 0000000000000000000000000000000000000000..5b79f6c5eb1032d70d97bf49cb2052bb49ec7a81 GIT binary patch literal 3553 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 +#include +#include + +class MWMapCallbackAdapter +{ + public: + virtual void init(Ice::StringSeq) = 0; + virtual void join(const std::shared_ptr&) = 0; + virtual void leave(const std::shared_ptr&) = 0; + virtual void send(const std::shared_ptr&) = 0; +}; + +class MWMap +{ + public: + MWMap(bool trace, const std::shared_ptr& logger); + void reserve(const std::string&); + void unreserve(const std::string&); + void join(const std::string&, const std::shared_ptr&); + void leave(const std::string&); + long long send(const std::string&, std::string); + + private: + + using MWMapCallbackMap = std::map>; + + MWMapCallbackMap _members; + std::set _reserved; + std::mutex _mutex; + const bool _trace; + const std::shared_ptr _logger; +}; + +#endif diff --git a/include/MWSessionI.h b/include/MWSessionI.h new file mode 100644 index 0000000..15972c5 --- /dev/null +++ b/include/MWSessionI.h @@ -0,0 +1,28 @@ +#ifndef MW_SESSION_I_H +#define MW_SESSION_I_H + +#include +#include + +class MWSessionI : public MW::MWSession +{ +public: + + MWSessionI(const std::shared_ptr&, const std::string&, bool trace, const std::shared_ptr& logger); + + virtual void setCallback(std::shared_ptr, const Ice::Current&) override; + virtual long long send(std::string, const Ice::Current&) override; + virtual void destroy(const Ice::Current&) override; + +private: + + const std::shared_ptr _MWMap; + const std::string _name; + std::shared_ptr _callback; + bool _destroy = false; + std::mutex _mutex; + const bool _trace; + const std::shared_ptr _logger; +}; + +#endif diff --git a/include/MWSessionManagerI.h b/include/MWSessionManagerI.h new file mode 100644 index 0000000..5e93323 --- /dev/null +++ b/include/MWSessionManagerI.h @@ -0,0 +1,25 @@ + +#ifndef MW_SESSION_MANAGER_I_H +#define MW_SESSION_MANAGER_I_H + +#include +#include +#include + +class MWSessionManagerI : public Glacier2::SessionManager +{ +public: + + MWSessionManagerI(const std::shared_ptr&, bool trace, const std::shared_ptr& logger); + + virtual std::shared_ptr create(std::string, + std::shared_ptr, + const Ice::Current&) override; +private: + + const std::shared_ptr _MWMap; + const bool _trace; + const std::shared_ptr _logger; +}; + +#endif diff --git a/src/MW.ice b/src/MW.ice new file mode 100644 index 0000000..ac76f41 --- /dev/null +++ b/src/MW.ice @@ -0,0 +1,77 @@ +#pragma once +#include "Ice/BuiltinSequences.ice" +#include "Glacier2/Session.ice" + +module MW +{ +/** + * + * The InvalidMessageException is raised when a user sends an invalid + * message to the server. A message is considered invalid if the + * message size exceeds the maximum message size. + * + **/ + +exception InvalidMessageException +{ + /** + * + * The reason why the message was rejected by the server. + * + **/ + string reason; +} + +class MWMapEvent +{ + /** The timestamp. */ + long timestamp; + /** The name of the user. */ + string name; +} + +/** + * + * A sequence of state changes in the MW map. + * + * @see MWMapEvent + * + **/ +sequence MWMapEventSeq; + +/** + * + * This event is generated when a user joins the MW map. + * + * @see MWMapEvent + * + **/ +class UserJoinedEvent extends MWMapEvent +{ +} + +/** + * + * This event is generated when a user leaves the MW map. + * + * @see MWMapEvent + * + **/ +class UserLeftEvent extends MWMapEvent +{ +} + +/** + * + * This event is generated when a user sends a posotion in the + * map. + * + * @see MWMapEvent + * + **/ +class PositionEvent extends MWMapEvent +{ + /** The contents of the message. */ + string message; +} +} \ No newline at end of file diff --git a/src/MWMap.cpp b/src/MWMap.cpp new file mode 100644 index 0000000..7f81ece --- /dev/null +++ b/src/MWMap.cpp @@ -0,0 +1,99 @@ + +#include + +using namespace std; + +MWMap::MWMap(bool trace, const shared_ptr& logger) : + _trace(trace), + _logger(logger) +{ +} + +void +MWMap::reserve(const string& name) +{ + lock_guard sync(_mutex); + if(_reserved.find(name) != _reserved.end() || _members.find(name) != _members.end()) + { + throw runtime_error("The name " + name + " is already in use."); + } + _reserved.insert(name); +} + +void +MWMap::unreserve(const string& name) +{ + lock_guard sync(_mutex); + _reserved.erase(name); +} + +void +MWMap::join(const string& name, const shared_ptr& callback) +{ + lock_guard sync(_mutex); + long long timestamp = chrono::duration_cast(chrono::system_clock::now().time_since_epoch()).count(); + + _reserved.erase(name); + + Ice::StringSeq names; + for(const auto& q : _members) + { + names.push_back(q.first); + } + + callback->init(move(names)); + + _members[name] = callback; + + auto e = make_shared(timestamp, name); + for(const auto& q: _members) + { + q.second->join(e); + } + + if(_trace) + { + Ice::Trace out(_logger, "info"); + out << "User '" << name << "' joined the MW Map."; + } +} + +void +MWMap::leave(const string& name) +{ + lock_guard sync(_mutex); + long long timestamp = chrono::duration_cast(chrono::system_clock::now().time_since_epoch()).count(); + + _members.erase(name); + + auto e = make_shared(timestamp, name); + for(const auto& q: _members) + { + q.second->leave(e); + } + + if(_trace) + { + Ice::Trace out(_logger, "info"); + out << "User '" << name << "' left the MWMap."; + } +} + +Ice::Long +MWMap::send(const string& name, string message) +{ + lock_guard sync(_mutex); + long long timestamp = chrono::duration_cast(chrono::system_clock::now().time_since_epoch()).count(); + + auto e = make_shared(timestamp, name, message); + for(const auto& q: _members) + { + q.second->send(e); + } + if(_trace) + { + Ice::Trace out(_logger, "info"); + out << name << ": " << message; + } + return timestamp; +} diff --git a/src/MWServer.cpp b/src/MWServer.cpp new file mode 100644 index 0000000..9ae5db3 --- /dev/null +++ b/src/MWServer.cpp @@ -0,0 +1,84 @@ +#include +#include +// #include + +using namespace std; + +class MWServer : public Ice::Service +{ +public: + + virtual bool start(int argc, char* argv[], int&) override; + virtual bool stop() override; + +private: + + shared_ptr _adapter; +}; + +bool +MWServer::start(int, char*[], int& status) +{ + // int timeout = communicator()->getProperties()->getPropertyAsIntWithDefault("PollingChatSessionTimeout", 10); + bool traceEnabled = communicator()->getProperties()->getPropertyAsIntWithDefault("Server.Trace", 0) != 0; + auto logger = communicator()->getLogger(); + + try + { + _adapter = communicator()->createObjectAdapter("MWServer"); + + auto mwmap = make_shared(traceEnabled, logger); + if(traceEnabled) + { + Ice::Trace out(logger, "info"); + out << "MW room created ok."; + } + _adapter->add(make_shared(mwmap, traceEnabled, logger), + Ice::stringToIdentity("MWSessionManager")); + + if(traceEnabled) + { + Ice::Trace out(logger, "info"); + out << "MW session manager created ok."; + } + // _adapter->add(make_shared(chatRoom, timeout, traceEnabled, logger), + // Ice::stringToIdentity("PollingChatSessionFactory")); + + // if(traceEnabled) + // { + // Ice::Trace out(logger, "info"); + // out << "Polling chat session factory created ok."; + // } + + _adapter->activate(); + if(traceEnabled) + { + Ice::Trace out(logger, "info"); + out << "MW server started ok."; + } + } + catch(const Ice::LocalException&) + { + status = 1; + throw; + } + status = 0; + return true; +} + +bool +MWServer::stop() +{ + return true; +} + +int +main(int argc, char* argv[]) +{ +#ifdef ICE_STATIC_LIBS + Ice::registerIceSSL(); + Ice::registerIceWS(); +#endif + MWServer app; + return app.main(argc, argv); +} diff --git a/src/MWSession.ice b/src/MWSession.ice new file mode 100644 index 0000000..6c96a44 --- /dev/null +++ b/src/MWSession.ice @@ -0,0 +1,113 @@ +#pragma once + +#include +#include +#include + +module MW +{ + +/** + * + * The MWRoomCallback interface is the interface that clients implement + * as their callback object. + * + * The server calls operations of this interface to communicate + * with connected clients. + * + **/ +interface MWMapCallback +{ + /** + * + * The server invokes this operation when the client sets the callback + * for a session. This provides the client with the initial list of users + * currently in the MW room. + * + * @param users The names of users currently in the MW room. + * + **/ + void init(Ice::StringSeq users); + + /** + * + * The server invokes this operation to deliver a message + * that was sent to the MW room. + * + * @param name The name of the user that send the message. + * + * @param message The contents of the message. + * + * @param timestamp The time at which the message was sent. + * + **/ + void send(long timestamp, string name, string message); + + /** + * + * The server invokes this operation when a user joins + * the MW room. + * + * @param name The name of the user that joined the MW room. + * + * @param timestamp The time at which the user joined the MW room. + * + **/ + void join(long timestamp, string name); + + /** + * + * The servers invokes this operation when a user leaves + * the MW room. + * + * @param name The name of the user that left the MW room. + * + * @param timestamp The time at which the user left the MW room. + * + **/ + void leave(long timestamp, string name); +} + +/** + * + * A MWSession is a custom Glacier2::Session for clients that use + * Glacier2 and support callbacks (such as C++, C# and clients). + * + * @see Glacier2::Session + * + **/ +interface MWSession extends Glacier2::Session +{ + /** + * + * The setCallback operation is called by clients to set the + * callback used to receive notification of activity in the + * room. Clients receive notifications as soon as they call this + * operation (before setCallback returns). + * + * The first callback made by the server is a call to + * MWRoomCallback::init, which delivers the current list of + * users to the client. + * + * @param cb The callback the server uses to deliver notifications. + * + * @see MWRoomCallback + * + **/ + void setCallback(MWMapCallback* cb); + + /** + * + * Send a message to the MW room. + * + * @param message The message to be sent. + * + * @return The time at which the message is sent. + * + * @throws InvalidMessageException should the message be invalid. + * + **/ + long send(string message) throws InvalidMessageException; +} + +} \ No newline at end of file diff --git a/src/MWSessionI.cpp b/src/MWSessionI.cpp new file mode 100644 index 0000000..79b7cbb --- /dev/null +++ b/src/MWSessionI.cpp @@ -0,0 +1,210 @@ + +#include +#include + +using namespace std; + +class SessionCallbackAdapter : public MWMapCallbackAdapter, + public enable_shared_from_this +{ +public: + + SessionCallbackAdapter(const shared_ptr& callback, + const shared_ptr& session, + bool trace, const shared_ptr& logger, const std::string& name) : + _callback(callback), + _session(session), + _trace(trace), + _logger(logger), + _name(name) + { + } + + void init(Ice::StringSeq users) override + { + auto self = shared_from_this(); + try + { + _callback->initAsync(users, nullptr, [self](std::exception_ptr eptr) { self->failed(eptr); }); + } + catch(const Ice::CommunicatorDestroyedException&) + { + // Ignored server is being shutdown + } + } + + void join(const shared_ptr& e) override + { + auto self = shared_from_this(); + try + { + _callback->joinAsync(e->timestamp, e->name, nullptr, [self](exception_ptr eptr) { self->failed(eptr); }); + } + catch(const Ice::CommunicatorDestroyedException&) + { + // Ignored server is being shutdown + } + } + + void leave(const shared_ptr& e) override + { + auto self = shared_from_this(); + try + { + _callback->leaveAsync(e->timestamp, e->name, nullptr, [self](exception_ptr eptr) { self->failed(eptr); }); + } + catch(const Ice::CommunicatorDestroyedException&) + { + // Ignored server is being shutdown + } + } + + void send(const shared_ptr& e) override + { + auto self = shared_from_this(); + try + { + _callback->sendAsync(e->timestamp, e->name, e->message, nullptr, [self](exception_ptr eptr) { self->failed(eptr); }); + } + catch(const Ice::CommunicatorDestroyedException&) + { + // Ignored server is being shutdown + } + } + + void failed(exception_ptr) + { + if(_trace) + { + Ice::Trace out(_logger, "info"); + out << "Error sending request to user '" << _name << "'. The user's session will be destroyed."; + } + try + { + _session->ice_endpoints(Ice::EndpointSeq())->destroy(); // Collocated call. + } + catch(const Ice::LocalException&) + { + } + } + +private: + + const shared_ptr _callback; + const shared_ptr _session; + const bool _trace; + const shared_ptr _logger; + const string _name; +}; + +MWSessionI::MWSessionI(const shared_ptr& MWMap, const string& name, bool trace, const shared_ptr& logger) : + _MWMap(MWMap), + _name(name), + _trace(trace), + _logger(logger) +{ +} + +void +MWSessionI::setCallback(shared_ptr callback, const Ice::Current& current) +{ + lock_guard sync(_mutex); + if(_destroy) + { + if(_trace) + { + Ice::Trace out(_logger, "info"); + out << "User '" << _name << "' tried to set the session callback but the session is already destroyed."; + } + throw Ice::ObjectNotExistException(__FILE__, __LINE__); + } + + if(_callback || !callback) + { + return; + } + + Ice::Context ctx; + ctx["_fwd"] = "o"; + _callback = make_shared( + callback->ice_context(ctx), + Ice::uncheckedCast(current.adapter->createProxy(current.id)), + _trace, _logger, _name); + _MWRoom->join(_name, _callback); +} + +long long +MWSessionI::send(string message, const Ice::Current&) +{ + lock_guard sync(_mutex); + if(_destroy) + { + if(_trace) + { + Ice::Trace out(_logger, "info"); + out << "User '" << _name << "' tried to send a message but the session is already destroyed."; + } + throw Ice::ObjectNotExistException(__FILE__, __LINE__); + } + if(!_callback) + { + if(_trace) + { + Ice::Trace out(_logger, "info"); + out << "User '" << _name << "' tried to send a message without setting the callback."; + } + throw MW::InvalidMessageException("You cannot send messages until you join the MW Map."); + } + string msg; + try + { + msg = validateMessage(message); + } + catch(const exception& ex) + { + if(_trace) + { + Ice::Trace out(_logger, "info"); + out << "User '" << _name << "' sent an invalid message:\n" << ex; + } + throw MW::InvalidMessageException(ex.what()); + } + return _MWMap->send(_name, move(msg)); +} + +void +MWSessionI::destroy(const Ice::Current& current) +{ + lock_guard sync(_mutex); + if(_destroy) + { + if(_trace) + { + Ice::Trace out(_logger, "info"); + out << "Trying to destroy the session for user '" << _name << "' but the session is already destroyed."; + } + throw Ice::ObjectNotExistException(__FILE__, __LINE__); + } + try + { + current.adapter->remove(current.id); + if(_callback) + { + _MWMap->leave(_name); + } + else + { + _MWMap->unreserve(_name); + } + } + catch(const Ice::ObjectAdapterDeactivatedException&) + { + // No need to clean up, the server is shutting down. + } + if(_trace) + { + Ice::Trace out(_logger, "info"); + out << "Push session for user '" << _name << "' destroyed."; + } + _destroy = true; +} diff --git a/src/MWSessionManagerI.cpp b/src/MWSessionManagerI.cpp new file mode 100644 index 0000000..3eddb46 --- /dev/null +++ b/src/MWSessionManagerI.cpp @@ -0,0 +1,66 @@ +#include +#include +#include + +using namespace std; + +ChatSessionManagerI::ChatSessionManagerI(const shared_ptr& chatRoom, bool trace, + const shared_ptr& logger) : + _chatRoom(chatRoom), + _trace(trace), + _logger(logger) +{ +} + +shared_ptr +ChatSessionManagerI::create(string name, + shared_ptr sessionControl, + const Ice::Current& current) +{ + string vname; + try + { + vname = validateName(name); + _chatRoom->reserve(vname); + } + catch(const exception& ex) + { + if(_trace) + { + Ice::Trace out(_logger, "info"); + out << "Cannot create push session:\n" << ex; + } + throw Glacier2::CannotCreateSessionException(ex.what()); + } + + shared_ptr proxy; + try + { + auto session = make_shared(_chatRoom, vname, _trace, _logger); + proxy = Ice::uncheckedCast(current.adapter->addWithUUID(session)); + + Ice::IdentitySeq ids; + ids.push_back(proxy->ice_getIdentity()); + sessionControl->identities()->add(ids); + } + catch(const Ice::LocalException& ex) + { + if(_trace) + { + Ice::Trace out(_logger, "info"); + out << "Cannot create push session for user '" << vname << "':\n" << ex; + } + if(proxy) + { + proxy->destroy(); + } + throw Glacier2::CannotCreateSessionException("internal server error"); + } + + if(_trace) + { + Ice::Trace out(_logger, "info"); + out << "Push session created for user '" << vname << "'."; + } + return proxy; +} diff --git a/src/Makefile b/src/Makefile new file mode 100644 index 0000000..1b87c1e --- /dev/null +++ b/src/Makefile @@ -0,0 +1,29 @@ +CC=c++ +IDIR =../include +CFLAGS=-I. -DICE_CPP11_MAPPING -I $(IDIR) -std=c++11 + +ODIR=obj +LDIR =../lib + +LIBS=-lm -lIce++11 + +_DEPS = MW.h MWMap.h MWSession.h MWSessionI.h MWSessionManagerI.h +DEPS = $(patsubst %,$(IDIR)/%,$(_DEPS)) + +_OBJ = MW.o MWServer.o MWMap.o MWSession.o MWSesionManagerI.o MWUtils.o +OBJ = $(patsubst %,$(ODIR)/%,$(_OBJ)) + +$(ODIR)/%.o: %.cpp $(DEPS) + $(CC) -c -o $@ $< $(CFLAGS) + +slice: + slice2cpp -I. -I../../ice/slice *.ice + mv *.h ../include + +mwserver: $(OBJ) + $(CC) -o $@ $^ $(CFLAGS) $(LIBS) + +.PHONY: clean + +clean: + rm -f $(ODIR)/*.o *~ core $(INCDIR)/*~ diff --git a/src/Printer.ice b/src/Printer.ice deleted file mode 100644 index 610a9e8..0000000 --- a/src/Printer.ice +++ /dev/null @@ -1,7 +0,0 @@ -module Demo -{ - interface Printer - { - void printString(string s); - } -} \ No newline at end of file diff --git a/src/Server.cpp b/src/Server.cpp deleted file mode 100644 index b5a4803..0000000 --- a/src/Server.cpp +++ /dev/null @@ -1,38 +0,0 @@ -#include -#include - -using namespace std; -using namespace Demo; - -class PrinterI : public Printer -{ -public: - virtual void printString(string s, const Ice::Current&) override; -}; - -void -PrinterI::printString(string s, const Ice::Current&) -{ - cout << s << endl; -} - -int -main(int argc, char* argv[]) -{ - try - { - Ice::CommunicatorHolder ich(argc, argv); - // Server implementation here ... - auto adapter = ich->createObjectAdapterWithEndpoints("SimplePrinterAdapter", "default -p 10000"); - auto servant = make_shared(); - adapter->add(servant, ich->stringToIdentity("SimplePrinter")); - adapter->activate(); - ich->waitForShutdown(); - } - catch(const std::exception& e) - { - cerr << e.what() << endl; - return 1; - } - return 0; -} diff --git a/src/config.glacier2router b/src/config.glacier2router new file mode 100644 index 0000000..69912f7 --- /dev/null +++ b/src/config.glacier2router @@ -0,0 +1,84 @@ +# +# Set the Glacier2 instance name. +# +Glacier2.InstanceName=MWServer + +# +# The client-visible endpoint of Glacier2. This should be an endpoint +# visible from the public Internet. +# +Glacier2.Client.Endpoints=ssl -p 4064 -t 10000 -h 127.0.0.1:tcp -p 4502 -t 10000 -h 127.0.0.1 + +# +# The server-visible endpoint of Glacier2. This endpoint is only +# required if callbacks are needed (leave empty otherwise). This +# should be an endpoint on an internal network (like 192.168.x.x), or +# on the loopback, so that the server is not directly accessible from +# the Internet. +# +Glacier2.Server.Endpoints=tcp -h 127.0.0.1 + +# +# The proxy of the session manager. +# +Glacier2.SessionManager=ChatSessionManager:tcp -h 127.0.0.1 -p 10001 + +# +# Accept only requests to the machine where the session manager is +# running. +# +Glacier2.Filter.Address.Accept=127.0.0.1:10001 + +# +# For this demo, we use the null permissions verifier. This permissions +# verifier allows any user-id / password combination. +# +Glacier2.PermissionsVerifier=MWServer/NullPermissionsVerifier + +# +# The timeout for inactive sessions. If any client session is inactive +# for longer than this value, the session expires and is removed. The +# unit is seconds. +# +Glacier2.SessionTimeout=30 + +# +# Turn off buffering, it's not useful for the chat demo. +# +Glacier2.Server.Buffered=0 +Glacier2.Client.Buffered=0 + +# +# Security Tracing +# +# 0 = no security tracing +# 1 = trace messages +# +#IceSSL.Trace.Security=1 + +# +# SSL Configuration +# +Ice.Plugin.IceSSL=IceSSL:createIceSSL +IceSSL.DefaultDir=../certs +IceSSL.CAs=cacert.pem +IceSSL.CertFile=server.p12 +IceSSL.Password=password +IceSSL.Keychain=../../../certs/glacier2.keychain +IceSSL.KeychainPassword=password +IceSSL.VerifyPeer=0 + +# +# Ice Tracing +# +#Ice.Trace.Network=1 +#Ice.Warn.Connections=1 +#Ice.Trace.Protocol=1 + +# +# We configure the server thread pool as we want the glacier2router +# to be multi threaded. +# + +Ice.ThreadPool.Server.Size=4 +Ice.ThreadPool.Server.SizeMax=10 diff --git a/src/config.mwserver b/src/config.mwserver new file mode 100644 index 0000000..0a56a71 --- /dev/null +++ b/src/config.mwserver @@ -0,0 +1,44 @@ +# +# The endpoint of the session server's object adapter. This should be +# an endpoint on an internal network (like 192.168.x.x), or on the +# loopback, so that the session server is not directly accessible from +# the Internet. +# +ChatServer.Endpoints=tcp -h 127.0.0.1 -p 10001 + +# +# Warn about connection exceptions +# +#Ice.Warn.Connections=1 + +# +# Network Tracing +# +# 0 = no network tracing +# 1 = trace connection establishment and closure +# 2 = like 1, but more detailed +# 3 = like 2, but also trace data transfer +# +#Ice.Trace.Network=3 + +# +# Protocol Tracing +# +# 0 = no protocol tracing +# 1 = trace protocol messages +# +#Ice.Trace.Protocol=1 + +# +# Chat Server Tracing +# +# 0 = disable chat server tracing +# 1 = enable chat server tracing +Server.Trace=1 + +# +# We configure the server thread pool as we want the chatserver +# to be multi threaded. +# +Ice.ThreadPool.Server.Size=4 +Ice.ThreadPool.Server.SizeMax=10 \ No newline at end of file