00001 #ifndef SST_REGCLI_H
00002 #define SST_REGCLI_H
00003
00004 #include <QSet>
00005
00006 #include "reg.h"
00007 #include "sock.h"
00008 #include "timer.h"
00009
00010 class QHostInfo;
00011
00012
00013 namespace SST {
00014
00015 class Host;
00016 class RegReceiver;
00017
00018 class RegClient : public QObject
00019 {
00020 friend class RegReceiver;
00021 Q_OBJECT
00022
00023 private:
00024 static const int maxRereg = 60*60*1000;
00025
00026
00027 Host *const h;
00028
00029 enum State {
00030 Idle = 0,
00031 Resolve,
00032 Insert1,
00033 Insert2,
00034 Registered,
00035 } state;
00036
00037
00038 QString srvname;
00039 quint16 srvport;
00040 int lookupid;
00041 QList<QHostAddress> addrs;
00042 RegInfo inf;
00043
00044
00045 QByteArray idi;
00046 QByteArray ni;
00047 QByteArray nhi;
00048 QByteArray chal;
00049 QByteArray key;
00050 QByteArray sig;
00051
00052
00053 QSet<QByteArray> lookups;
00054 QSet<QByteArray> punches;
00055 QSet<QString> searches;
00056
00057
00058 Timer retrytimer;
00059 bool persist;
00060
00061 Timer reregtimer;
00062
00063
00064 QString err;
00065
00066
00067
00068 void fail(const QString &error);
00069
00070 public:
00071 RegClient(Host *h, QObject *parent = NULL);
00072 ~RegClient();
00073
00074
00075 inline RegInfo info() { return inf; }
00076 inline void setInfo(const RegInfo &info) { inf = info; }
00077
00078
00079
00080 void registerAt(const QString &srvhost,
00081 quint16 port = REGSERVER_DEFAULT_PORT);
00082
00083
00084 void reregister();
00085
00086 inline QString serverName() { return srvname; }
00087 inline quint16 serverPort() { return srvport; }
00088
00089 inline QString errorString() { return err; }
00090 inline void setErrorString(const QString &err) { this->err = err; }
00091
00092 inline bool idle() { return state == Idle; }
00093 inline bool registered() { return state == Registered; }
00094 inline bool registering() { return !idle() && !registered(); }
00095
00096
00097
00098 inline void setPersistent(bool persist) { this->persist = persist; }
00099 inline bool isPersistent() { return persist; }
00100
00101
00102
00103
00104
00105 void lookup(const QByteArray &id, bool notify = false);
00106
00107
00108
00109
00110 void search(const QString &text);
00111
00112
00113
00114 void disconnect();
00115
00116
00117 signals:
00118 void stateChanged();
00119 void lookupDone(const QByteArray &id, const Endpoint &loc,
00120 const RegInfo &info);
00121 void lookupNotify(const QByteArray &id, const Endpoint &loc,
00122 const RegInfo &info);
00123 void searchDone(const QString &text, const QList<QByteArray> ids,
00124 bool complete);
00125
00126 private:
00127 void goInsert1();
00128 void sendInsert1();
00129 void gotInsert1Reply(XdrStream &rs);
00130
00131 void goInsert2();
00132 void sendInsert2();
00133 void gotInsert2Reply(XdrStream &rs);
00134
00135 void sendLookup(const QByteArray &id, bool notify);
00136 void gotLookupReply(XdrStream &rs, bool isnotify);
00137
00138 void sendSearch(const QString &text);
00139 void gotSearchReply(XdrStream &rs);
00140
00141 void send(const QByteArray &msg);
00142
00143
00144 private slots:
00145 void resolveDone(const QHostInfo &hi);
00146 void timeout(bool fail);
00147 void reregTimeout();
00148 };
00149
00150
00151
00152 class RegReceiver : public SocketReceiver
00153 {
00154 friend class RegClient;
00155 friend class RegHostState;
00156
00157 private:
00158
00159
00160 QHash<QByteArray,RegClient*> nhihash;
00161
00162
00163 RegReceiver(Host *h);
00164 virtual void receive(QByteArray &msg, XdrStream &ds,
00165 const SocketEndpoint &src);
00166 };
00167
00168
00169 class RegHostState : public QObject
00170 {
00171 friend class RegClient;
00172 Q_OBJECT
00173
00174 private:
00175 RegReceiver rcvr;
00176
00177
00178
00179 QSet<RegClient*> cliset;
00180
00181 public:
00182 inline RegHostState(Host *h) : rcvr(h) { }
00183
00184 inline QList<RegClient*> regClients()
00185 { return cliset.toList(); }
00186
00187 signals:
00188 void regClientCreate(RegClient *rc);
00189 void regClientDestroy(RegClient *rc);
00190 };
00191
00192 }
00193
00194 #endif // SST_REGCLI_H