Mercurial > pidgin
annotate libpurple/protocols/qq/qq_network.c @ 23904:7ff461621d77
Correct documentation about list account options to reflect what the key and
value of the PurpleKeyValuePair actually represent (based on what Pidgin does
with them). (Since the only protocol to use them, silc, uses the same string
for the key and the value, no harm came of me having written incorrect
documentation last time.)
author | Will Thompson <will.thompson@collabora.co.uk> |
---|---|
date | Sun, 17 Aug 2008 11:10:39 +0000 |
parents | 91169093449d |
children | 147ada94a1d8 |
rev | line source |
---|---|
23050 | 1 /** |
2 * @file qq_network.c | |
3 * | |
4 * purple | |
5 * | |
6 * Purple is the legal property of its developers, whose names are too numerous | |
7 * to list here. Please refer to the COPYRIGHT file distributed with this | |
8 * source distribution. | |
9 * | |
10 * This program is free software; you can redistribute it and/or modify | |
11 * it under the terms of the GNU General Public License as published by | |
12 * the Free Software Foundation; either version 2 of the License, or | |
13 * (at your option) any later version. | |
14 * | |
15 * This program is distributed in the hope that it will be useful, | |
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
18 * GNU General Public License for more details. | |
19 * | |
20 * You should have received a copy of the GNU General Public License | |
21 * along with this program; if not, write to the Free Software | |
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA | |
23 */ | |
24 | |
25 #include "cipher.h" | |
26 #include "debug.h" | |
27 #include "internal.h" | |
28 | |
29 #ifdef _WIN32 | |
30 #define random rand | |
31 #define srandom srand | |
32 #endif | |
33 | |
34 #include "buddy_info.h" | |
23638
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
35 #include "group_info.h" |
23050 | 36 #include "group_free.h" |
23695
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
37 #include "qq_crypt.h" |
23050 | 38 #include "header_info.h" |
23638
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
39 #include "qq_base.h" |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
40 #include "buddy_list.h" |
23050 | 41 #include "packet_parse.h" |
42 #include "qq_network.h" | |
23051
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
43 #include "qq_trans.h" |
23050 | 44 #include "utils.h" |
23638
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
45 #include "qq_process.h" |
23050 | 46 |
23051
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
47 /* set QQ_RECONNECT_MAX to 1, when test reconnecting */ |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
48 #define QQ_RECONNECT_MAX 4 |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
49 #define QQ_RECONNECT_INTERVAL 5000 |
23638
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
50 #define QQ_KEEP_ALIVE_INTERVAL 60000 |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
51 #define QQ_TRANS_INTERVAL 10000 |
23051
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
52 |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
53 static gboolean set_new_server(qq_data *qd) |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
54 { |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
55 gint count; |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
56 gint index; |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
57 GList *it = NULL; |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
58 |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
59 g_return_val_if_fail(qd != NULL, FALSE); |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
60 |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
61 if (qd->servers == NULL) { |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
62 purple_debug(PURPLE_DEBUG_INFO, "QQ", "Server list is NULL\n"); |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
63 return FALSE; |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
64 } |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
65 |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
66 if (qd->real_hostname) { |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
67 purple_debug(PURPLE_DEBUG_INFO, "QQ", "free real_hostname\n"); |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
68 g_free(qd->real_hostname); |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
69 qd->real_hostname = NULL; |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
70 } |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
71 |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
72 /* remove server used before */ |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
73 if (qd->server_name != NULL) { |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
74 purple_debug(PURPLE_DEBUG_INFO, "QQ", |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
75 "Remove previous server [%s]\n", qd->server_name); |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
76 qd->servers = g_list_remove(qd->servers, qd->server_name); |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
77 qd->server_name = NULL; |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
78 } |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
79 |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
80 count = g_list_length(qd->servers); |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
81 purple_debug(PURPLE_DEBUG_INFO, "QQ", "Server list has %d\n", count); |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
82 if (count <= 0) { |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
83 /* no server left, disconnect when result is false */ |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
84 qd->servers = NULL; |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
85 return FALSE; |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
86 } |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
87 |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
88 /* get new server */ |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
89 index = random() % count; |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
90 it = g_list_nth(qd->servers, index); |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
91 qd->server_name = it->data; /* do not free server_name */ |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
92 if (qd->server_name == NULL || strlen(qd->server_name) <= 0 ) { |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
93 purple_debug(PURPLE_DEBUG_INFO, "QQ", "Server name at %d is empty\n", index); |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
94 return FALSE; |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
95 } |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
96 |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
97 qd->real_hostname = g_strdup(qd->server_name); |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
98 qd->real_port = qd->user_port; |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
99 |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
100 qd->reconnect_times = QQ_RECONNECT_MAX; |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
101 |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
102 purple_debug(PURPLE_DEBUG_INFO, "QQ", |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
103 "set new server to %s:%d\n", qd->real_hostname, qd->real_port); |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
104 return TRUE; |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
105 } |
23050 | 106 |
107 static gint packet_get_header(guint8 *header_tag, guint16 *source_tag, | |
108 guint16 *cmd, guint16 *seq, guint8 *buf) | |
109 { | |
110 gint bytes = 0; | |
111 bytes += qq_get8(header_tag, buf + bytes); | |
112 bytes += qq_get16(source_tag, buf + bytes); | |
113 bytes += qq_get16(cmd, buf + bytes); | |
114 bytes += qq_get16(seq, buf + bytes); | |
115 return bytes; | |
116 } | |
117 | |
23051
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
118 static gboolean reconnect_later_cb(gpointer data) |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
119 { |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
120 PurpleConnection *gc; |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
121 qq_data *qd; |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
122 |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
123 gc = (PurpleConnection *) data; |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
124 g_return_val_if_fail(gc != NULL && gc->proto_data != NULL, FALSE); |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
125 qd = (qq_data *) gc->proto_data; |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
126 |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
127 qd->reconnect_timeout = 0; |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
128 |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
129 qq_connect(gc->account); |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
130 return FALSE; /* timeout callback stops */ |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
131 } |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
132 |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
133 static void reconnect_later(PurpleConnection *gc) |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
134 { |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
135 qq_data *qd; |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
136 |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
137 g_return_if_fail(gc != NULL && gc->proto_data != NULL); |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
138 qd = (qq_data *) gc->proto_data; |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
139 |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
140 qd->reconnect_times--; |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
141 if (qd->reconnect_times < 0) { |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
142 if ( set_new_server(qd) != TRUE) { |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
143 purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
144 _("Failed to connect server")); |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
145 return; |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
146 } |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
147 } |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
148 |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
149 purple_debug(PURPLE_DEBUG_INFO, "QQ", |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
150 "Reconnect to server %s:%d next retries %d in %d ms\n", |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
151 qd->real_hostname, qd->real_port, |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
152 qd->reconnect_times, QQ_RECONNECT_INTERVAL); |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
153 |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
154 qd->reconnect_timeout = purple_timeout_add(QQ_RECONNECT_INTERVAL, |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
155 reconnect_later_cb, gc); |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
156 } |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
157 |
23050 | 158 /* process the incoming packet from qq_pending */ |
159 static void packet_process(PurpleConnection *gc, guint8 *buf, gint buf_len) | |
160 { | |
161 qq_data *qd; | |
162 gint bytes, bytes_not_read; | |
163 | |
164 gboolean prev_login_status; | |
165 | |
166 guint8 header_tag; | |
167 guint16 source_tag; | |
168 guint16 cmd; | |
23051
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
169 guint16 seq; /* May be ack_seq or send_seq, depends on cmd */ |
23695
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
170 |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
171 guint8 room_cmd; |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
172 guint32 room_id; |
23051
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
173 |
23638
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
174 qq_transaction *trans; |
23050 | 175 |
176 g_return_if_fail(buf != NULL && buf_len > 0); | |
177 | |
178 qd = (qq_data *) gc->proto_data; | |
179 | |
180 prev_login_status = qd->logged_in; | |
181 | |
23051
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
182 /* Len, header and tail tag have been checked before */ |
23050 | 183 bytes = 0; |
184 bytes += packet_get_header(&header_tag, &source_tag, &cmd, &seq, buf + bytes); | |
185 | |
23695
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
186 #if 1 |
23050 | 187 purple_debug(PURPLE_DEBUG_INFO, "QQ", |
23695
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
188 "==> [%05d] 0x%04X %s, from (0x%04X %s) len %d\n", |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
189 seq, cmd, qq_get_cmd_desc(cmd), source_tag, qq_get_ver_desc(source_tag), buf_len); |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
190 #endif |
23050 | 191 bytes_not_read = buf_len - bytes - 1; |
192 | |
23051
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
193 /* ack packet, we need to update send tranactions */ |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
194 /* we do not check duplication for server ack */ |
23638
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
195 trans = qq_trans_find_rcved(qd, cmd, seq); |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
196 if (trans == NULL) { |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
197 /* new server command */ |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
198 qq_trans_add_server_cmd(qd, cmd, seq, buf + bytes, bytes_not_read); |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
199 if ( qd->logged_in ) { |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
200 qq_proc_cmd_server(gc, cmd, seq, buf + bytes, bytes_not_read); |
23051
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
201 } |
23638
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
202 return; |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
203 } |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
204 |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
205 if (qq_trans_is_dup(trans)) { |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
206 purple_debug(PURPLE_DEBUG_WARNING, |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
207 "QQ", "dup [%05d] %s, discard...\n", seq, qq_get_cmd_desc(cmd)); |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
208 return; |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
209 } |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
210 |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
211 if (qq_trans_is_server(trans)) { |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
212 if ( qd->logged_in ) { |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
213 qq_proc_cmd_server(gc, cmd, seq, buf + bytes, bytes_not_read); |
23051
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
214 } |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
215 return; |
23050 | 216 } |
217 | |
218 /* this is the length of all the encrypted data (also remove tail tag */ | |
23695
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
219 if (cmd == QQ_CMD_ROOM) { |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
220 room_cmd = qq_trans_get_room_cmd(trans); |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
221 room_id = qq_trans_get_room_id(trans); |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
222 #if 1 |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
223 purple_debug(PURPLE_DEBUG_INFO, "QQ", |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
224 "%s (0x%02X ) for room %d, len %d\n", |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
225 qq_get_room_cmd_desc(room_cmd), room_cmd, room_id, buf_len); |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
226 #endif |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
227 qq_proc_room_cmd_reply(gc, seq, room_cmd, room_id, buf + bytes, bytes_not_read); |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
228 } else { |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
229 qq_proc_cmd_reply(gc, cmd, seq, buf + bytes, bytes_not_read); |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
230 } |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
231 |
23051
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
232 /* check is redirect or not, and do it now */ |
23050 | 233 if (qd->is_redirect) { |
23051
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
234 /* free resource except real_hostname and port */ |
23050 | 235 qq_disconnect(gc); |
23051
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
236 qd->reconnect_times = QQ_RECONNECT_MAX; |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
237 reconnect_later(gc); |
23050 | 238 return; |
239 } | |
240 | |
241 if (prev_login_status != qd->logged_in && qd->logged_in == TRUE) { | |
242 /* logged_in, but we have packets before login */ | |
23638
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
243 qq_trans_process_before_login(qd); |
23050 | 244 } |
245 } | |
246 | |
247 static void tcp_pending(gpointer data, gint source, PurpleInputCondition cond) | |
248 { | |
249 PurpleConnection *gc; | |
250 qq_data *qd; | |
23051
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
251 guint8 buf[1024]; /* set to 16 when test tcp_rxqueue */ |
23050 | 252 gint buf_len; |
253 gint bytes; | |
254 | |
255 guint8 *pkt; | |
256 guint16 pkt_len; | |
257 | |
258 gchar *error_msg; | |
259 guint8 *jump; | |
260 gint jump_len; | |
261 | |
262 gc = (PurpleConnection *) data; | |
263 g_return_if_fail(gc != NULL && gc->proto_data != NULL); | |
264 | |
265 if(cond != PURPLE_INPUT_READ) { | |
266 purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, | |
267 _("Socket error")); | |
268 return; | |
269 } | |
270 | |
271 qd = (qq_data *) gc->proto_data; | |
272 | |
273 /* test code, not using tcp_rxqueue | |
274 memset(pkt,0, sizeof(pkt)); | |
275 buf_len = read(qd->fd, pkt, sizeof(pkt)); | |
276 if (buf_len > 2) { | |
277 packet_process(gc, pkt + 2, buf_len - 2); | |
278 } | |
279 return; | |
280 */ | |
281 | |
282 buf_len = read(qd->fd, buf, sizeof(buf)); | |
283 if (buf_len < 0) { | |
284 if (errno == EAGAIN) | |
285 /* No worries */ | |
286 return; | |
287 | |
288 error_msg = g_strdup_printf(_("Lost connection with server:\n%d, %s"), errno, g_strerror(errno)); | |
289 purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, error_msg); | |
290 g_free(error_msg); | |
291 return; | |
292 } else if (buf_len == 0) { | |
293 purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, | |
294 _("Server closed the connection.")); | |
295 return; | |
296 } | |
297 | |
23561
bdb38a8bf721
20080717-05-1-fix-keep-alive ccpaging <ecc_hy(at)hotmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23052
diff
changeset
|
298 /* keep alive will be sent in 30 seconds since last_receive |
bdb38a8bf721
20080717-05-1-fix-keep-alive ccpaging <ecc_hy(at)hotmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23052
diff
changeset
|
299 * QQ need a keep alive packet in every 60 seconds |
bdb38a8bf721
20080717-05-1-fix-keep-alive ccpaging <ecc_hy(at)hotmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23052
diff
changeset
|
300 gc->last_received = time(NULL); |
bdb38a8bf721
20080717-05-1-fix-keep-alive ccpaging <ecc_hy(at)hotmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23052
diff
changeset
|
301 */ |
23638
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
302 /* |
23050 | 303 purple_debug(PURPLE_DEBUG_INFO, "TCP_PENDING", |
304 "Read %d bytes from socket, rxlen is %d\n", buf_len, qd->tcp_rxlen); | |
23638
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
305 */ |
23050 | 306 qd->tcp_rxqueue = g_realloc(qd->tcp_rxqueue, buf_len + qd->tcp_rxlen); |
307 memcpy(qd->tcp_rxqueue + qd->tcp_rxlen, buf, buf_len); | |
308 qd->tcp_rxlen += buf_len; | |
309 | |
310 pkt = g_newa(guint8, MAX_PACKET_SIZE); | |
311 while (1) { | |
312 if (qd->tcp_rxlen < QQ_TCP_HEADER_LENGTH) { | |
313 break; | |
314 } | |
315 | |
316 bytes = 0; | |
317 bytes += qq_get16(&pkt_len, qd->tcp_rxqueue + bytes); | |
318 if (qd->tcp_rxlen < pkt_len) { | |
319 break; | |
320 } | |
321 | |
23638
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
322 /* |
23050 | 323 purple_debug(PURPLE_DEBUG_INFO, "TCP_PENDING", |
324 "Packet len is %d bytes, rxlen is %d\n", pkt_len, qd->tcp_rxlen); | |
23638
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
325 */ |
23050 | 326 if ( pkt_len < QQ_TCP_HEADER_LENGTH |
327 || *(qd->tcp_rxqueue + bytes) != QQ_PACKET_TAG | |
328 || *(qd->tcp_rxqueue + pkt_len - 1) != QQ_PACKET_TAIL) { | |
23051
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
329 /* HEY! This isn't even a QQ. What are you trying to pull? */ |
23050 | 330 |
331 purple_debug(PURPLE_DEBUG_ERROR, "TCP_PENDING", | |
332 "Packet error, failed to check header and tail tag\n"); | |
333 | |
334 jump = memchr(qd->tcp_rxqueue + 1, QQ_PACKET_TAIL, qd->tcp_rxlen - 1); | |
335 if ( !jump ) { | |
336 purple_debug(PURPLE_DEBUG_INFO, "TCP_PENDING", | |
337 "Failed to find next QQ_PACKET_TAIL, clear receive buffer\n"); | |
338 g_free(qd->tcp_rxqueue); | |
339 qd->tcp_rxqueue = NULL; | |
340 qd->tcp_rxlen = 0; | |
341 return; | |
342 } | |
343 | |
23051
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
344 /* jump and over QQ_PACKET_TAIL */ |
23050 | 345 jump_len = (jump - qd->tcp_rxqueue) + 1; |
346 purple_debug(PURPLE_DEBUG_INFO, "TCP_PENDING", | |
347 "Find next QQ_PACKET_TAIL at %d, jump %d bytes\n", jump_len, jump_len + 1); | |
348 g_memmove(qd->tcp_rxqueue, jump, qd->tcp_rxlen - jump_len); | |
349 qd->tcp_rxlen -= jump_len; | |
350 continue; | |
351 } | |
352 | |
353 memset(pkt, 0, MAX_PACKET_SIZE); | |
354 g_memmove(pkt, qd->tcp_rxqueue + bytes, pkt_len - bytes); | |
355 | |
23051
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
356 /* jump to next packet */ |
23050 | 357 qd->tcp_rxlen -= pkt_len; |
358 if (qd->tcp_rxlen) { | |
23638
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
359 /* |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
360 purple_debug(PURPLE_DEBUG_ERROR, "TCP_PENDING", "shrink tcp_rxqueue to %d\n", qd->tcp_rxlen); |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
361 */ |
23050 | 362 jump = g_memdup(qd->tcp_rxqueue + pkt_len, qd->tcp_rxlen); |
363 g_free(qd->tcp_rxqueue); | |
364 qd->tcp_rxqueue = jump; | |
365 } else { | |
23638
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
366 /* purple_debug(PURPLE_DEBUG_ERROR, "TCP_PENDING", "free tcp_rxqueue\n"); */ |
23050 | 367 g_free(qd->tcp_rxqueue); |
368 qd->tcp_rxqueue = NULL; | |
369 } | |
370 | |
371 if (pkt == NULL) { | |
372 continue; | |
373 } | |
23051
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
374 /* do not call packet_process before jump |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
375 * packet_process may call disconnect and destory tcp_rxqueue */ |
23050 | 376 packet_process(gc, pkt, pkt_len - bytes); |
377 } | |
378 } | |
379 | |
380 static void udp_pending(gpointer data, gint source, PurpleInputCondition cond) | |
381 { | |
382 PurpleConnection *gc; | |
383 qq_data *qd; | |
384 guint8 *buf; | |
385 gint buf_len; | |
386 | |
387 gc = (PurpleConnection *) data; | |
388 g_return_if_fail(gc != NULL && gc->proto_data != NULL); | |
389 | |
390 if(cond != PURPLE_INPUT_READ) { | |
391 purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, | |
392 _("Socket error")); | |
393 return; | |
394 } | |
395 | |
396 qd = (qq_data *) gc->proto_data; | |
397 g_return_if_fail(qd->fd >= 0); | |
398 | |
399 buf = g_newa(guint8, MAX_PACKET_SIZE); | |
400 | |
401 /* here we have UDP proxy suppport */ | |
402 buf_len = read(qd->fd, buf, MAX_PACKET_SIZE); | |
403 if (buf_len <= 0) { | |
404 purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, | |
405 _("Unable to read from socket")); | |
406 return; | |
407 } | |
408 | |
23561
bdb38a8bf721
20080717-05-1-fix-keep-alive ccpaging <ecc_hy(at)hotmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23052
diff
changeset
|
409 /* keep alive will be sent in 30 seconds since last_receive |
bdb38a8bf721
20080717-05-1-fix-keep-alive ccpaging <ecc_hy(at)hotmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23052
diff
changeset
|
410 * QQ need a keep alive packet in every 60 seconds |
bdb38a8bf721
20080717-05-1-fix-keep-alive ccpaging <ecc_hy(at)hotmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23052
diff
changeset
|
411 gc->last_received = time(NULL); |
bdb38a8bf721
20080717-05-1-fix-keep-alive ccpaging <ecc_hy(at)hotmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23052
diff
changeset
|
412 */ |
23050 | 413 |
414 if (buf_len < QQ_UDP_HEADER_LENGTH) { | |
415 if (buf[0] != QQ_PACKET_TAG || buf[buf_len - 1] != QQ_PACKET_TAIL) { | |
416 qq_hex_dump(PURPLE_DEBUG_ERROR, "UDP_PENDING", | |
417 buf, buf_len, | |
418 "Received packet is too short, or no header and tail tag"); | |
419 return; | |
420 } | |
421 } | |
422 | |
423 packet_process(gc, buf, buf_len); | |
424 } | |
425 | |
426 static gint udp_send_out(qq_data *qd, guint8 *data, gint data_len) | |
427 { | |
428 gint ret; | |
429 | |
430 g_return_val_if_fail(qd != NULL && qd->fd >= 0 && data != NULL && data_len > 0, -1); | |
431 | |
23638
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
432 /* |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
433 purple_debug(PURPLE_DEBUG_INFO, "UDP_SEND_OUT", "Send %d bytes to socket %d\n", data_len, qd->fd); |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
434 */ |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
435 |
23050 | 436 errno = 0; |
437 ret = send(qd->fd, data, data_len, 0); | |
438 if (ret < 0 && errno == EAGAIN) { | |
439 return ret; | |
440 } | |
441 | |
442 if (ret < 0) { | |
443 /* TODO: what to do here - do we really have to disconnect? */ | |
23638
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
444 purple_debug(PURPLE_DEBUG_ERROR, "UDP_SEND_OUT", "Send failed: %d, %s\n", errno, g_strerror(errno)); |
23050 | 445 purple_connection_error_reason(qd->gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, g_strerror(errno)); |
446 } | |
447 return ret; | |
448 } | |
449 | |
450 static void tcp_can_write(gpointer data, gint source, PurpleInputCondition cond) | |
451 { | |
452 qq_data *qd = data; | |
453 int ret, writelen; | |
454 | |
455 writelen = purple_circ_buffer_get_max_read(qd->tcp_txbuf); | |
456 if (writelen == 0) { | |
457 purple_input_remove(qd->tx_handler); | |
458 qd->tx_handler = 0; | |
459 return; | |
460 } | |
461 | |
462 ret = write(qd->fd, qd->tcp_txbuf->outptr, writelen); | |
463 purple_debug(PURPLE_DEBUG_ERROR, "TCP_CAN_WRITE", | |
464 "total %d bytes is sent %d\n", writelen, ret); | |
465 | |
466 if (ret < 0 && errno == EAGAIN) | |
467 return; | |
468 else if (ret < 0) { | |
469 /* TODO: what to do here - do we really have to disconnect? */ | |
470 purple_connection_error_reason(qd->gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, | |
471 _("Write Error")); | |
472 return; | |
473 } | |
474 | |
475 purple_circ_buffer_mark_read(qd->tcp_txbuf, ret); | |
476 } | |
477 | |
478 static gint tcp_send_out(qq_data *qd, guint8 *data, gint data_len) | |
479 { | |
480 gint ret; | |
481 | |
482 g_return_val_if_fail(qd != NULL && qd->fd >= 0 && data != NULL && data_len > 0, -1); | |
483 | |
23051
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
484 /* |
23638
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
485 purple_debug(PURPLE_DEBUG_INFO, "TCP_SEND_OUT", "Send %d bytes to socket %d\n", data_len, qd->fd); |
23051
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
486 */ |
23050 | 487 |
488 if (qd->tx_handler == 0) { | |
489 ret = write(qd->fd, data, data_len); | |
490 } else { | |
491 ret = -1; | |
492 errno = EAGAIN; | |
493 } | |
494 | |
23638
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
495 /* |
23050 | 496 purple_debug(PURPLE_DEBUG_INFO, "TCP_SEND_OUT", |
497 "Socket %d, total %d bytes is sent %d\n", qd->fd, data_len, ret); | |
23638
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
498 */ |
23050 | 499 if (ret < 0 && errno == EAGAIN) { |
23051
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
500 /* socket is busy, send later */ |
23638
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
501 purple_debug(PURPLE_DEBUG_INFO, "TCP_SEND_OUT", "Socket is busy and send later\n"); |
23050 | 502 ret = 0; |
503 } else if (ret <= 0) { | |
23051
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
504 /* TODO: what to do here - do we really have to disconnect? */ |
23050 | 505 purple_debug(PURPLE_DEBUG_ERROR, "TCP_SEND_OUT", |
506 "Send to socket %d failed: %d, %s\n", qd->fd, errno, g_strerror(errno)); | |
507 purple_connection_error_reason(qd->gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, g_strerror(errno)); | |
508 return ret; | |
509 } | |
510 | |
511 if (ret < data_len) { | |
512 purple_debug(PURPLE_DEBUG_INFO, "TCP_SEND_OUT", | |
513 "Add %d bytes to buffer\n", data_len - ret); | |
514 if (qd->tx_handler == 0) { | |
515 qd->tx_handler = purple_input_add(qd->fd, PURPLE_INPUT_WRITE, tcp_can_write, qd); | |
516 } | |
517 purple_circ_buffer_append(qd->tcp_txbuf, data + ret, data_len - ret); | |
518 } | |
519 return ret; | |
520 } | |
521 | |
23638
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
522 static gboolean network_timeout(gpointer data) |
23050 | 523 { |
23638
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
524 PurpleConnection *gc = (PurpleConnection *) data; |
23050 | 525 qq_data *qd; |
23638
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
526 gboolean is_lost_conn; |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
527 |
23050 | 528 g_return_val_if_fail(gc != NULL && gc->proto_data != NULL, TRUE); |
23638
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
529 qd = (qq_data *) gc->proto_data; |
23050 | 530 |
23638
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
531 is_lost_conn = qq_trans_scan(qd); |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
532 if (is_lost_conn) { |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
533 purple_connection_error_reason(gc, |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
534 PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Connection lost")); |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
535 return TRUE; |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
536 } |
23050 | 537 |
23638
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
538 if ( !qd->logged_in ) { |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
539 return TRUE; |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
540 } |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
541 |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
542 qd->itv_count.keep_alive--; |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
543 if (qd->itv_count.keep_alive <= 0) { |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
544 qd->itv_count.keep_alive = qd->itv_config.keep_alive; |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
545 qq_send_packet_keep_alive(gc); |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
546 return TRUE; |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
547 } |
23050 | 548 |
23638
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
549 if (qd->itv_config.update <= 0) { |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
550 return TRUE; |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
551 } |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
552 |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
553 qd->itv_count.update--; |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
554 if (qd->itv_count.update <= 0) { |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
555 qd->itv_count.update = qd->itv_config.update; |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
556 qq_send_packet_get_buddies_online(gc, 0); |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
557 |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
558 qq_send_cmd_group_all_get_online_members(gc); |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
559 return TRUE; |
23050 | 560 } |
561 | |
562 return TRUE; /* if return FALSE, timeout callback stops */ | |
563 } | |
564 | |
565 /* the callback function after socket is built | |
566 * we setup the qq protocol related configuration here */ | |
567 static void qq_connect_cb(gpointer data, gint source, const gchar *error_message) | |
568 { | |
569 qq_data *qd; | |
570 PurpleConnection *gc; | |
23051
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
571 gchar *conn_msg; |
23050 | 572 const gchar *passwd; |
23638
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
573 PurpleAccount *account ; |
23050 | 574 |
575 gc = (PurpleConnection *) data; | |
576 | |
577 if (!PURPLE_CONNECTION_IS_VALID(gc)) { | |
578 purple_debug(PURPLE_DEBUG_INFO, "QQ_CONN", "Invalid connection\n"); | |
579 close(source); | |
580 return; | |
581 } | |
582 | |
583 g_return_if_fail(gc != NULL && gc->proto_data != NULL); | |
584 | |
585 qd = (qq_data *) gc->proto_data; | |
23638
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
586 account = purple_connection_get_account(gc); |
23050 | 587 |
588 /* Connect is now complete; clear the PurpleProxyConnectData */ | |
589 qd->connect_data = NULL; | |
590 | |
591 if (source < 0) { /* socket returns -1 */ | |
23051
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
592 purple_debug(PURPLE_DEBUG_INFO, "QQ_CONN", "Invalid connection, source is < 0\n"); |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
593 qq_disconnect(gc); |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
594 reconnect_later(gc); |
23050 | 595 return; |
596 } | |
597 | |
23051
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
598 /* _qq_show_socket("Got login socket", source); */ |
23050 | 599 |
600 /* QQ use random seq, to minimize duplicated packets */ | |
601 srandom(time(NULL)); | |
602 qd->send_seq = random() & 0x0000ffff; | |
603 qd->fd = source; | |
604 qd->logged_in = FALSE; | |
605 qd->channel = 1; | |
606 qd->uid = strtol(purple_account_get_username(purple_connection_get_account(gc)), NULL, 10); | |
607 | |
608 /* now generate md5 processed passwd */ | |
609 passwd = purple_account_get_password(purple_connection_get_account(gc)); | |
23638
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
610 |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
611 /* use twice-md5 of user password as session key since QQ 2003iii */ |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
612 qq_get_md5(qd->password_twice_md5, sizeof(qd->password_twice_md5), |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
613 (guint8 *)passwd, strlen(passwd)); |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
614 qq_get_md5(qd->password_twice_md5, sizeof(qd->password_twice_md5), |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
615 qd->password_twice_md5, sizeof(qd->password_twice_md5)); |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
616 |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
617 g_return_if_fail(qd->network_timeout == 0); |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
618 qd->itv_config.resend = purple_account_get_int(account, "resend_interval", 10); |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
619 if (qd->itv_config.resend <= 0) qd->itv_config.resend = 10; |
23050 | 620 |
23638
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
621 qd->itv_config.keep_alive = purple_account_get_int(account, "keep_alive_interval", 60); |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
622 if (qd->itv_config.keep_alive < 30) qd->itv_config.keep_alive = 30; |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
623 qd->itv_config.keep_alive /= qd->itv_config.resend; |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
624 qd->itv_count.keep_alive = qd->itv_config.keep_alive; |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
625 |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
626 qd->itv_config.update = purple_account_get_int(account, "update_interval", 300); |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
627 if (qd->itv_config.update > 0) { |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
628 if (qd->itv_config.update < qd->itv_config.keep_alive) { |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
629 qd->itv_config.update = qd->itv_config.keep_alive; |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
630 } |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
631 qd->itv_config.update /= qd->itv_config.resend; |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
632 qd->itv_count.update = qd->itv_config.update; |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
633 } else { |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
634 qd->itv_config.update = 0; |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
635 } |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
636 |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
637 qd->network_timeout = purple_timeout_add(qd->itv_config.resend *1000, network_timeout, gc); |
23050 | 638 |
639 if (qd->use_tcp) | |
640 gc->inpa = purple_input_add(qd->fd, PURPLE_INPUT_READ, tcp_pending, gc); | |
641 else | |
642 gc->inpa = purple_input_add(qd->fd, PURPLE_INPUT_READ, udp_pending, gc); | |
643 | |
644 /* Update the login progress status display */ | |
23051
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
645 conn_msg = g_strdup_printf("Login as %d", qd->uid); |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
646 purple_connection_update_progress(gc, conn_msg, QQ_CONNECT_STEPS - 1, QQ_CONNECT_STEPS); |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
647 g_free(conn_msg); |
23050 | 648 |
23638
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
649 qq_send_packet_token(gc); |
23050 | 650 } |
651 | |
652 static void udp_can_write(gpointer data, gint source, PurpleInputCondition cond) | |
653 { | |
654 PurpleConnection *gc; | |
655 qq_data *qd; | |
656 socklen_t len; | |
657 int error=0, ret; | |
658 | |
659 gc = (PurpleConnection *) data; | |
660 g_return_if_fail(gc != NULL && gc->proto_data != NULL); | |
661 | |
662 qd = (qq_data *) gc->proto_data; | |
663 | |
664 | |
665 purple_debug_info("proxy", "Connected.\n"); | |
666 | |
667 /* | |
668 * getsockopt after a non-blocking connect returns -1 if something is | |
669 * really messed up (bad descriptor, usually). Otherwise, it returns 0 and | |
670 * error holds what connect would have returned if it blocked until now. | |
671 * Thus, error == 0 is success, error == EINPROGRESS means "try again", | |
672 * and anything else is a real error. | |
673 * | |
674 * (error == EINPROGRESS can happen after a select because the kernel can | |
675 * be overly optimistic sometimes. select is just a hint that you might be | |
676 * able to do something.) | |
677 */ | |
678 len = sizeof(error); | |
679 ret = getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len); | |
680 if (ret == 0 && error == EINPROGRESS) | |
681 return; /* we'll be called again later */ | |
682 | |
683 purple_input_remove(qd->tx_handler); | |
684 qd->tx_handler = 0; | |
685 if (ret < 0 || error != 0) { | |
686 if(ret != 0) | |
687 error = errno; | |
688 | |
689 close(source); | |
690 | |
691 purple_debug_error("proxy", "getsockopt SO_ERROR check: %s\n", g_strerror(error)); | |
692 | |
693 qq_connect_cb(gc, -1, _("Unable to connect")); | |
694 return; | |
695 } | |
696 | |
697 qq_connect_cb(gc, source, NULL); | |
698 } | |
699 | |
700 static void udp_host_resolved(GSList *hosts, gpointer data, const char *error_message) { | |
701 PurpleConnection *gc; | |
702 qq_data *qd; | |
703 struct sockaddr server_addr; | |
704 int addr_size; | |
705 gint fd = -1; | |
706 int flags; | |
707 | |
708 gc = (PurpleConnection *) data; | |
709 g_return_if_fail(gc != NULL && gc->proto_data != NULL); | |
710 | |
711 qd = (qq_data *) gc->proto_data; | |
712 | |
23051
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
713 /* udp_query_data must be set as NULL. |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
714 * Otherwise purple_dnsquery_destroy in qq_disconnect cause glib double free error */ |
23050 | 715 qd->udp_query_data = NULL; |
716 | |
717 if (!hosts || !hosts->data) { | |
718 purple_connection_error_reason(gc, | |
719 PURPLE_CONNECTION_ERROR_NETWORK_ERROR, | |
720 _("Couldn't resolve host")); | |
721 return; | |
722 } | |
723 | |
724 addr_size = GPOINTER_TO_INT(hosts->data); | |
725 hosts = g_slist_remove(hosts, hosts->data); | |
726 memcpy(&server_addr, hosts->data, addr_size); | |
727 g_free(hosts->data); | |
728 | |
729 hosts = g_slist_remove(hosts, hosts->data); | |
730 while(hosts) { | |
731 hosts = g_slist_remove(hosts, hosts->data); | |
732 g_free(hosts->data); | |
733 hosts = g_slist_remove(hosts, hosts->data); | |
734 } | |
735 | |
736 fd = socket(PF_INET, SOCK_DGRAM, 0); | |
737 if (fd < 0) { | |
738 purple_debug(PURPLE_DEBUG_ERROR, "QQ", | |
739 "Unable to create socket: %s\n", g_strerror(errno)); | |
740 return; | |
741 } | |
742 | |
743 /* we use non-blocking mode to speed up connection */ | |
744 flags = fcntl(fd, F_GETFL); | |
745 fcntl(fd, F_SETFL, flags | O_NONBLOCK); | |
23712
91169093449d
More leaks of fds to client processes.
Daniel Atallah <daniel.atallah@gmail.com>
parents:
23695
diff
changeset
|
746 #ifndef _WIN32 |
91169093449d
More leaks of fds to client processes.
Daniel Atallah <daniel.atallah@gmail.com>
parents:
23695
diff
changeset
|
747 fcntl(fd, F_SETFD, FD_CLOEXEC); |
91169093449d
More leaks of fds to client processes.
Daniel Atallah <daniel.atallah@gmail.com>
parents:
23695
diff
changeset
|
748 #endif |
23050 | 749 |
750 /* From Unix-socket-FAQ: http://www.faqs.org/faqs/unix-faq/socket/ | |
751 * | |
752 * If a UDP socket is unconnected, which is the normal state after a | |
753 * bind() call, then send() or write() are not allowed, since no | |
754 * destination is available; only sendto() can be used to send data. | |
755 * | |
756 * Calling connect() on the socket simply records the specified address | |
757 * and port number as being the desired communications partner. That | |
758 * means that send() or write() are now allowed; they use the destination | |
759 * address and port given on the connect call as the destination of packets. | |
760 */ | |
761 if (connect(fd, &server_addr, addr_size) >= 0) { | |
762 purple_debug(PURPLE_DEBUG_INFO, "QQ", "Connected.\n"); | |
763 flags = fcntl(fd, F_GETFL); | |
764 fcntl(fd, F_SETFL, flags & ~O_NONBLOCK); | |
765 qq_connect_cb(gc, fd, NULL); | |
766 return; | |
767 } | |
768 | |
769 /* [EINPROGRESS] | |
770 * The socket is marked as non-blocking and the connection cannot be | |
771 * completed immediately. It is possible to select for completion by | |
772 * selecting the socket for writing. | |
773 * [EINTR] | |
774 * A signal interrupted the call. | |
775 * The connection is established asynchronously. | |
776 */ | |
777 if ((errno == EINPROGRESS) || (errno == EINTR)) { | |
778 purple_debug(PURPLE_DEBUG_WARNING, "QQ", "Connect in asynchronous mode.\n"); | |
779 qd->tx_handler = purple_input_add(fd, PURPLE_INPUT_WRITE, udp_can_write, gc); | |
780 return; | |
781 } | |
782 | |
23052
ebad75b719f5
Sun Jun 29 22:00:12 CST 2008 csyfek@gmail.com
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23051
diff
changeset
|
783 purple_debug(PURPLE_DEBUG_ERROR, "QQ", "Connection failed: %s\n", g_strerror(errno)); |
23050 | 784 close(fd); |
785 } | |
786 | |
787 /* establish a generic QQ connection | |
788 * TCP/UDP, and direct/redirected */ | |
789 void qq_connect(PurpleAccount *account) | |
790 { | |
791 PurpleConnection *gc; | |
792 qq_data *qd; | |
23051
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
793 gchar *conn_msg; |
23050 | 794 |
795 gc = purple_account_get_connection(account); | |
796 g_return_if_fail(gc != NULL && gc->proto_data != NULL); | |
797 | |
798 qd = (qq_data *) gc->proto_data; | |
799 | |
23051
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
800 |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
801 /* test set_new_server |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
802 while (set_new_server(qd)) { |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
803 purple_debug(PURPLE_DEBUG_INFO, "QQ_TEST", |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
804 "New server %s:%d Real server %s:%d\n", |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
805 qd->server_name, qd->user_port, qd->real_hostname, qd->real_port); |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
806 } |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
807 purple_debug(PURPLE_DEBUG_INFO, "QQ_TEST", "qd->servers %lu\n", |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
808 qd->servers); |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
809 exit(1); |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
810 */ |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
811 if (qd->server_name == NULL) { |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
812 /* must be first call this function */ |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
813 if ( set_new_server(qd) != TRUE) { |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
814 purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
815 _("Failed to connect server")); |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
816 return; |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
817 } |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
818 } |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
819 |
23050 | 820 if (qd->real_hostname == NULL || qd->real_port == 0) { |
821 purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, | |
822 _("hostname is NULL or port is 0")); | |
823 return; | |
824 } | |
825 | |
23051
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
826 conn_msg = g_strdup_printf( _("Connecting server %s, retries %d"), |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
827 qd->real_hostname, qd->reconnect_times); |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
828 purple_connection_update_progress(gc, conn_msg, 1, QQ_CONNECT_STEPS); |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
829 g_free(conn_msg); |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
830 |
23050 | 831 if (qd->is_redirect) { |
832 purple_debug(PURPLE_DEBUG_INFO, "QQ", "Redirect to %s:%d\n", | |
833 qd->real_hostname, qd->real_port); | |
834 } | |
835 qd->is_redirect = FALSE; | |
836 | |
837 qd->fd = -1; | |
838 qd->tx_handler = 0; | |
839 | |
840 /* QQ connection via UDP/TCP. | |
841 * Now use Purple proxy function to provide TCP proxy support, | |
842 * and qq_udp_proxy.c to add UDP proxy support (thanks henry) */ | |
843 if(qd->use_tcp) { | |
844 purple_debug(PURPLE_DEBUG_INFO, "QQ", "TCP Connect to %s:%d\n", | |
845 qd->real_hostname, qd->real_port); | |
846 | |
847 /* TODO: is there a good default grow size? */ | |
848 purple_debug(PURPLE_DEBUG_INFO, "QQ", "Create tcp_txbuf\n"); | |
849 qd->tcp_txbuf = purple_circ_buffer_new(0); | |
850 | |
851 qd->connect_data = purple_proxy_connect(NULL, account, | |
852 qd->real_hostname, qd->real_port, qq_connect_cb, gc); | |
853 if (qd->connect_data == NULL) { | |
854 purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, | |
855 _("Unable to connect.")); | |
856 } | |
857 return; | |
858 } | |
859 | |
860 purple_debug(PURPLE_DEBUG_INFO, "QQ", "UDP Connect to %s:%d\n", | |
861 qd->real_hostname, qd->real_port); | |
862 | |
863 g_return_if_fail(qd->udp_query_data == NULL); | |
864 qd->udp_query_data = purple_dnsquery_a(qd->real_hostname, qd->real_port, | |
865 udp_host_resolved, gc); | |
866 if (qd->udp_query_data == NULL) { | |
867 purple_connection_error_reason(qd->gc, | |
868 PURPLE_CONNECTION_ERROR_NETWORK_ERROR, | |
869 _("Could not resolve hostname")); | |
870 } | |
871 } | |
872 | |
873 /* clean up qq_data structure and all its components | |
874 * always used before a redirectly connection */ | |
875 void qq_disconnect(PurpleConnection *gc) | |
876 { | |
877 qq_data *qd; | |
878 | |
879 g_return_if_fail(gc != NULL && gc->proto_data != NULL); | |
880 qd = (qq_data *) gc->proto_data; | |
881 | |
882 purple_debug(PURPLE_DEBUG_INFO, "QQ", "Disconnecting ...\n"); | |
23638
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
883 |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
884 if (qd->network_timeout > 0) { |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
885 purple_timeout_remove(qd->network_timeout); |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
886 qd->network_timeout = 0; |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
887 } |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
888 |
23050 | 889 /* finish all I/O */ |
890 if (qd->fd >= 0 && qd->logged_in) { | |
891 qq_send_packet_logout(gc); | |
892 } | |
893 | |
894 if (gc->inpa > 0) { | |
895 purple_input_remove(gc->inpa); | |
896 gc->inpa = 0; | |
897 } | |
898 | |
899 if (qd->fd >= 0) { | |
900 close(qd->fd); | |
901 qd->fd = -1; | |
902 } | |
903 | |
23051
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
904 if (qd->reconnect_timeout > 0) { |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
905 purple_timeout_remove(qd->reconnect_timeout); |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
906 qd->reconnect_timeout = 0; |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
907 } |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
908 |
23050 | 909 if (qd->connect_data != NULL) { |
910 purple_debug(PURPLE_DEBUG_INFO, "QQ", "Cancel connect_data\n"); | |
911 purple_proxy_connect_cancel(qd->connect_data); | |
912 } | |
913 | |
914 if(qd->tcp_txbuf != NULL) { | |
915 purple_debug(PURPLE_DEBUG_INFO, "QQ", "destroy tcp_txbuf\n"); | |
916 purple_circ_buffer_destroy(qd->tcp_txbuf); | |
23051
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
917 qd->tcp_txbuf = NULL; |
23050 | 918 } |
919 | |
920 if (qd->tx_handler) { | |
921 purple_input_remove(qd->tx_handler); | |
922 qd->tx_handler = 0; | |
923 } | |
924 if (qd->tcp_rxqueue != NULL) { | |
925 purple_debug(PURPLE_DEBUG_INFO, "QQ", "destroy tcp_rxqueue\n"); | |
926 g_free(qd->tcp_rxqueue); | |
927 qd->tcp_rxqueue = NULL; | |
928 qd->tcp_rxlen = 0; | |
929 } | |
930 | |
931 if (qd->udp_query_data != NULL) { | |
932 purple_debug(PURPLE_DEBUG_INFO, "QQ", "destroy udp_query_data\n"); | |
933 purple_dnsquery_destroy(qd->udp_query_data); | |
934 qd->udp_query_data = NULL; | |
935 } | |
936 | |
23638
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
937 qq_trans_remove_all(qd); |
23050 | 938 |
23638
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
939 if (qd->token) { |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
940 purple_debug(PURPLE_DEBUG_INFO, "QQ", "free token\n"); |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
941 g_free(qd->token); |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
942 qd->token = NULL; |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
943 qd->token_len = 0; |
23050 | 944 } |
23638
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
945 memset(qd->inikey, 0, sizeof(qd->inikey)); |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
946 memset(qd->password_twice_md5, 0, sizeof(qd->password_twice_md5)); |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
947 memset(qd->session_key, 0, sizeof(qd->session_key)); |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
948 memset(qd->session_md5, 0, sizeof(qd->session_md5)); |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
949 |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
950 qd->my_ip.s_addr = 0; |
23050 | 951 |
952 qq_group_free_all(qd); | |
953 qq_add_buddy_request_free(qd); | |
954 qq_info_query_free(qd); | |
955 qq_buddies_list_free(gc->account, qd); | |
956 } | |
957 | |
958 static gint encap(qq_data *qd, guint8 *buf, gint maxlen, guint16 cmd, guint16 seq, | |
959 guint8 *data, gint data_len) | |
960 { | |
961 gint bytes = 0; | |
962 g_return_val_if_fail(qd != NULL && buf != NULL && maxlen > 0, -1); | |
23695
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
963 g_return_val_if_fail(data != NULL && data_len > 0, -1); |
23050 | 964 |
965 /* QQ TCP packet has two bytes in the begining defines packet length | |
966 * so leave room here to store packet size */ | |
967 if (qd->use_tcp) { | |
968 bytes += qq_put16(buf + bytes, 0x0000); | |
969 } | |
970 /* now comes the normal QQ packet as UDP */ | |
971 bytes += qq_put8(buf + bytes, QQ_PACKET_TAG); | |
972 bytes += qq_put16(buf + bytes, QQ_CLIENT); | |
973 bytes += qq_put16(buf + bytes, cmd); | |
974 | |
975 bytes += qq_put16(buf + bytes, seq); | |
976 | |
977 bytes += qq_put32(buf + bytes, qd->uid); | |
978 bytes += qq_putdata(buf + bytes, data, data_len); | |
979 bytes += qq_put8(buf + bytes, QQ_PACKET_TAIL); | |
980 | |
23051
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
981 /* set TCP packet length at begin of the packet */ |
23050 | 982 if (qd->use_tcp) { |
983 qq_put16(buf, bytes); | |
984 } | |
985 | |
986 return bytes; | |
987 } | |
988 | |
23638
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
989 /* data has been encrypted before */ |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
990 gint qq_send_data(qq_data *qd, guint16 cmd, guint16 seq, gboolean need_ack, |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
991 guint8 *data, gint data_len) |
23050 | 992 { |
993 guint8 *buf; | |
994 gint buf_len; | |
995 gint bytes_sent; | |
996 | |
23051
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
997 g_return_val_if_fail(qd != NULL, -1); |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
998 g_return_val_if_fail(data != NULL && data_len > 0, -1); |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
999 |
23050 | 1000 buf = g_newa(guint8, MAX_PACKET_SIZE); |
1001 memset(buf, 0, MAX_PACKET_SIZE); | |
1002 buf_len = encap(qd, buf, MAX_PACKET_SIZE, cmd, seq, data, data_len); | |
1003 if (buf_len <= 0) { | |
1004 return -1; | |
1005 } | |
1006 | |
1007 if (qd->use_tcp) { | |
1008 bytes_sent = tcp_send_out(qd, buf, buf_len); | |
1009 } else { | |
1010 bytes_sent = udp_send_out(qd, buf, buf_len); | |
1011 } | |
1012 | |
23638
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
1013 if (need_ack) { |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
1014 qq_trans_add_client_cmd(qd, cmd, seq, data, data_len); |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
1015 } |
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
1016 |
23695
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1017 #if 1 |
23638
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
1018 /* qq_show_packet("QQ_SEND_DATA", buf, buf_len); */ |
23050 | 1019 purple_debug(PURPLE_DEBUG_INFO, "QQ", |
23695
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1020 "<== [%05d], 0x%04X %s, total %d bytes is sent %d\n", |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1021 seq, cmd, qq_get_cmd_desc(cmd), buf_len, bytes_sent); |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1022 #endif |
23050 | 1023 return bytes_sent; |
1024 } | |
1025 | |
23638
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
1026 /* Encrypt data with session_key, then call qq_send_data */ |
23051
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
1027 gint qq_send_cmd_detail(qq_data *qd, guint16 cmd, guint16 seq, gboolean need_ack, |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
1028 guint8 *data, gint data_len) |
23050 | 1029 { |
1030 guint8 *encrypted_data; | |
1031 gint encrypted_len; | |
1032 | |
23638
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
1033 g_return_val_if_fail(qd != NULL, -1); |
23051
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
1034 g_return_val_if_fail(data != NULL && data_len > 0, -1); |
23050 | 1035 |
23695
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1036 /* at most 16 bytes more */ |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1037 encrypted_data = g_newa(guint8, data_len + 16); |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1038 #if 0 |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1039 purple_debug(PURPLE_DEBUG_INFO, "QQ_ENCRYPT", |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1040 "Before %d: [%05d] 0x%04X %s\n", |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1041 data_len, seq, cmd, qq_get_cmd_desc(cmd)); |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1042 #endif |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1043 encrypted_len = qq_encrypt(encrypted_data, data, data_len, qd->session_key); |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1044 if (encrypted_len < 16) { |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1045 purple_debug(PURPLE_DEBUG_ERROR, "QQ_ENCRYPT", |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1046 "Error len %d: [%05d] 0x%04X %s\n", |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1047 encrypted_len, seq, cmd, qq_get_cmd_desc(cmd)); |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1048 return -1; |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1049 } |
23050 | 1050 |
23695
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1051 #if 0 |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1052 purple_debug(PURPLE_DEBUG_INFO, "QQ_ENCRYPT", |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1053 "After %d: [%05d] 0x%04X %s\n", |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1054 encrypted_len, seq, cmd, qq_get_cmd_desc(cmd)); |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1055 #endif |
23638
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
1056 return qq_send_data(qd, cmd, seq, need_ack, encrypted_data, encrypted_len); |
23050 | 1057 } |
23051
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
1058 |
23638
1c50f12b1c52
2008.08.02 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23561
diff
changeset
|
1059 /* set seq and need_ack, then call qq_send_cmd_detail */ |
23051
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
1060 gint qq_send_cmd(qq_data *qd, guint16 cmd, guint8 *data, gint data_len) |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
1061 { |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
1062 g_return_val_if_fail(qd != NULL, -1); |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
1063 g_return_val_if_fail(data != NULL && data_len > 0, -1); |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
1064 |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
1065 qd->send_seq++; |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
1066 return qq_send_cmd_detail(qd, cmd, qd->send_seq, TRUE, data, data_len); |
55f986ccbb6a
patch-05-reconnect-and-code-cleanup
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23050
diff
changeset
|
1067 } |
23695
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1068 |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1069 gint qq_send_room_cmd_noid(PurpleConnection *gc, guint8 room_cmd, |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1070 guint8 *data, gint data_len) |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1071 { |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1072 return qq_send_room_cmd(gc, room_cmd, 0, data, data_len); |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1073 } |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1074 |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1075 gint qq_send_room_cmd_only(PurpleConnection *gc, guint8 room_cmd, guint32 room_id) |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1076 { |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1077 g_return_val_if_fail(room_cmd > 0 && room_id > 0, -1); |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1078 return qq_send_room_cmd(gc, room_cmd, room_id, NULL, 0); |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1079 } |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1080 |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1081 gint qq_send_room_cmd(PurpleConnection *gc, guint8 room_cmd, guint32 room_id, |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1082 guint8 *data, gint data_len) |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1083 { |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1084 qq_data *qd; |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1085 |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1086 guint8 *buf; |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1087 gint buf_len; |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1088 guint8 *encrypted_data; |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1089 gint encrypted_len; |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1090 gint bytes_sent; |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1091 guint16 seq; |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1092 |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1093 g_return_val_if_fail(gc != NULL && gc->proto_data != NULL, -1); |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1094 qd = (qq_data *) gc->proto_data; |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1095 |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1096 buf = g_newa(guint8, MAX_PACKET_SIZE); |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1097 memset(buf, 0, MAX_PACKET_SIZE); |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1098 |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1099 /* encap room_cmd and room id to buf*/ |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1100 buf_len = 0; |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1101 buf_len += qq_put8(buf + buf_len, room_cmd); |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1102 if (room_id != 0) { |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1103 /* id 0 is for QQ Demo Group, now there are not existed*/ |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1104 buf_len += qq_put32(buf + buf_len, room_id); |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1105 } |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1106 if (data != NULL && data_len > 0) { |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1107 buf_len += qq_putdata(buf + buf_len, data, data_len); |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1108 } |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1109 qd->send_seq++; |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1110 seq = qd->send_seq; |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1111 |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1112 /* Encrypt to encrypted_data with session_key */ |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1113 /* at most 16 bytes more */ |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1114 encrypted_data = g_newa(guint8, buf_len + 16); |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1115 encrypted_len = qq_encrypt(encrypted_data, buf, buf_len, qd->session_key); |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1116 if (encrypted_len < 16) { |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1117 purple_debug(PURPLE_DEBUG_ERROR, "QQ_ENCRYPT", |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1118 "Error len %d: [%05d] QQ_CMD_ROOM.(0x%02X %s)\n", |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1119 encrypted_len, seq, room_cmd, qq_get_room_cmd_desc(room_cmd)); |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1120 return -1; |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1121 } |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1122 |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1123 /* Encap header to buf */ |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1124 buf_len = encap(qd, buf, MAX_PACKET_SIZE, QQ_CMD_ROOM, seq, encrypted_data, encrypted_len); |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1125 if (buf_len <= 0) { |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1126 return -1; |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1127 } |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1128 |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1129 if (qd->use_tcp) { |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1130 bytes_sent = tcp_send_out(qd, buf, buf_len); |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1131 } else { |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1132 bytes_sent = udp_send_out(qd, buf, buf_len); |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1133 } |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1134 |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1135 qq_trans_add_room_cmd(qd, seq, room_cmd, room_id, buf, buf_len); |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1136 |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1137 #if 1 |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1138 /* qq_show_packet("QQ_SEND_DATA", buf, buf_len); */ |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1139 purple_debug(PURPLE_DEBUG_INFO, "QQ", |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1140 "<== [%05d], QQ_CMD_ROOM.(0x%02X %s) to room %d, total %d bytes is sent %d\n", |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1141 seq, room_cmd, qq_get_room_cmd_desc(room_cmd), room_id, |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1142 buf_len, bytes_sent); |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1143 #endif |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1144 return bytes_sent; |
5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
SHiNE CsyFeK <csyfek@gmail.com>
parents:
23638
diff
changeset
|
1145 } |