1 /*
2  * MsgTrans - Message Transport Framework for DLang. Based on TCP, WebSocket, UDP transmission protocol.
3  *
4  * Copyright (C) 2019 HuntLabs
5  *
6  * Website: https://www.msgtrans.org
7  *
8  * Licensed under the Apache-2.0 License.
9  *
10  */
11 
12 module msgtrans.MessageTransportClient;
13 
14 import msgtrans.channel.ClientChannel;
15 import msgtrans.executor;
16 import msgtrans.MessageTransport;
17 import msgtrans.MessageBuffer;
18 import msgtrans.ee2e.crypto;
19 import hunt.logging.ConsoleLogger;
20 import msgtrans.TransportContext;
21 import core.time;
22 
23 /**
24  *
25  */
26 class MessageTransportClient : MessageTransport {
27     private bool _isConnected = false;
28     private ClientChannel _channel;
29     __gshared bool isEE2E;
30     __gshared ownkey_s  client_key;
31     __gshared peerkey_s server_key;
32     private CloseHandler  _closeHandler;
33     shared static this()
34     {
35         client_key = new ownkey_s;
36         server_key = new peerkey_s;
37         isEE2E = false;
38     }
39 
40     // private Duration _tickPeriod = 10.seconds;
41     // private Duration _ackTimeout = 30.seconds;
42     // private uint _missedAcks = 3;
43 
44     this(string name ,bool ee2e = false)
45     {
46         if (!name.length)
47         {
48             // Exeption?
49         }
50 
51         if(ee2e)
52         {
53             if (!generate_ecdh_keys(client_key.ec_pub_key, client_key.ec_priv_key))
54             {
55                 logError("ECDH-KEY generation failed.");
56             }
57             logInfo("%s",client_key.ec_pub_key);
58             /* Generate a random number that called salt */
59             if (!rand_salt(client_key.salt, CRYPTO_SALT_LEN))
60             {
61                 logError("Random salt generation failed.");
62             }
63             isEE2E = true;
64         }
65 
66         super(CLIENT_NAME_PREFIX ~ name);
67     }
68 
69     void closer(CloseHandler handler) {
70       _closeHandler = handler;
71     }
72 
73     MessageTransportClient channel(ClientChannel channel)
74     {
75         assert(channel !is null);
76         _channel = channel;
77         return this;
78     }
79 
80     bool connect()
81     {
82         assert(_channel !is null);
83 
84         try {
85           _channel.set(this);
86           _channel.connect();
87           _channel.onClose(_closeHandler);
88           _isConnected = true;
89         } catch(Exception e) {
90             return false;
91         }
92 
93         return true;
94     }
95 
96     void send(MessageBuffer buffer)
97     {
98         _channel.send(buffer);
99     }
100 
101     void send(uint id, ubyte[] msg ) {
102         // if(_channel.isConnected()) {
103 
104         // } else {
105         //     warning("Connection broken!");
106         // }
107         _channel.send(new MessageBuffer(id, msg));
108     }
109 
110     bool isConnected()
111     {
112       return _isConnected;
113     }
114     void send(uint id, string msg ) {
115         this.send(id, cast(ubyte[]) msg);
116     }
117 
118     void close() {
119         _channel.close();
120     }
121 
122   bool isClosed()
123   {
124     bool c = !_channel.isConnected;
125     if(c)
126     {
127       _isConnected = false;
128     }
129     return c;
130   }
131 }