summaryrefslogtreecommitdiff
path: root/libpurple/protocols/oscar/peer.h
blob: ec5d127f637c9d631f755f41db28a4878f3fdc78 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
/*
 * Purple's oscar protocol plugin
 * This file is the legal property of its developers.
 * Please see the AUTHORS file distributed alongside this file.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
*/

/*
 * OFT and ODC Services
 */

#ifndef _PEER_H_
#define _PEER_H_

#include "ft.h"
#include "network.h"
#include "proxy.h"

typedef struct _ChecksumData          ChecksumData;
typedef struct _OdcFrame              OdcFrame;
typedef struct _OftFrame              OftFrame;
typedef struct _ProxyFrame            ProxyFrame;
typedef struct _PeerConnection        PeerConnection;

#define PEER_CONNECTION_FLAG_INITIATED_BY_ME  0x0001
#define PEER_CONNECTION_FLAG_APPROVED         0x0002
#define PEER_CONNECTION_FLAG_TRIED_DIRECT     0x0004
#define PEER_CONNECTION_FLAG_TRIED_INCOMING   0x0008
#define PEER_CONNECTION_FLAG_TRIED_PROXY      0x0010
#define PEER_CONNECTION_FLAG_IS_INCOMING      0x0020

#define PEER_TYPE_PROMPT 0x0101 /* "I am going to send you this file, is that ok?" */
#define PEER_TYPE_RESUMEACCEPT 0x0106 /* We are accepting the resume */
#define PEER_TYPE_ACK 0x0202 /* "Yes, it is ok for you to send me that file" */
#define PEER_TYPE_DONE 0x0204 /* "I received that file with no problems" or "I already have that file, great!" */
#define PEER_TYPE_RESUME 0x0205 /* Resume transferring, sent by whoever receives */
#define PEER_TYPE_RESUMEACK 0x0207 /* Our resume accept was ACKed */

#define PEER_TYPE_GETFILE_REQUESTLISTING 0x1108 /* "I have a listing.txt file, do you want it?" */
#define PEER_TYPE_GETFILE_RECEIVELISTING 0x1209 /* "Yes, please send me your listing.txt file" */
#define PEER_TYPE_GETFILE_RECEIVEDLISTING 0x120a /* received corrupt listing.txt file? I'm just guessing about this one... */
#define PEER_TYPE_GETFILE_ACKLISTING 0x120b /* "I received the listing.txt file successfully" */
#define PEER_TYPE_GETFILE_REQUESTFILE 0x120c /* "Please send me this file" */

/*
 * For peer proxying
 */
#define PEER_PROXY_SERVER         "ars.oscar.aol.com"
#define PEER_PROXY_PORT           5190   /* The port we should always connect to */
#define PEER_PROXY_PACKET_VERSION 0x044a

/* Thanks to Keith Lea and the Joust project for documenting these */
#define PEER_PROXY_TYPE_ERROR   0x0001
#define PEER_PROXY_TYPE_CREATE  0x0002
#define PEER_PROXY_TYPE_CREATED 0x0003
#define PEER_PROXY_TYPE_JOIN    0x0004
#define PEER_PROXY_TYPE_READY   0x0005

struct _OdcFrame
{
	/* guchar magic[4]; */        /* 0 */
	/* guint16 length; */         /* 4 */
	guint16 type;                 /* 6 */
	guint16 subtype;              /* 8 */
	/* Unknown */                 /* 10 */
	guchar cookie[8];		      /* 12 */
	/* Unknown */
	/* guint32 payloadlength; */  /* 28 */
	guint16 encoding;             /* 32 */
	/* Unknown */
	guint16 flags;                /* 38 */
	/* Unknown */
	guchar bn[32];                /* 44 */
	/* Unknown */
	ByteStream payload;           /* 76 */
};

struct _OftFrame
{
	/* guchar magic[4]; */   /* 0 */
	/* guint16 length; */    /* 4 */
	guint16 type;            /* 6 */
	guchar cookie[8];        /* 8 */
	guint16 encrypt;         /* 16 */
	guint16 compress;        /* 18 */
	guint16 totfiles;        /* 20 */
	guint16 filesleft;       /* 22 */
	guint16 totparts;        /* 24 */
	guint16 partsleft;       /* 26 */
	guint32 totsize;         /* 28 */
	guint32 size;            /* 32 */
	guint32 modtime;         /* 36 */
	guint32 checksum;        /* 40 */
	guint32 rfrcsum;         /* 44 */
	guint32 rfsize;          /* 48 */
	guint32 cretime;         /* 52 */
	guint32 rfcsum;          /* 56 */
	guint32 nrecvd;          /* 60 */
	guint32 recvcsum;        /* 64 */
	guchar idstring[32];     /* 68 */
	guint8 flags;            /* 100 */
	guint8 lnameoffset;      /* 101 */
	guint8 lsizeoffset;      /* 102 */
	guchar dummy[69];        /* 103 */
	guchar macfileinfo[16];  /* 172 */
	guint16 nencode;         /* 188 */
	guint16 nlanguage;       /* 190 */
	guchar *name;            /* 192 */
	size_t name_length;
	/* Payload? */           /* 256 */
};

struct _ProxyFrame
{
	/* guint16 length; */    /* 0 */
	guint16 version;         /* 2 */
	guint16 type;            /* 4 */
	guint32 unknown;         /* 6 */
	guint16 flags;           /* 10 */
	ByteStream payload;      /* 12 */
};

struct _PeerConnection
{
	OscarData *od;
	guint64 type;
	char *bn;
	guchar magic[4];
	guchar cookie[8];
	guint16 lastrequestnumber;

	gboolean ready;
	int flags;                       /**< Bitmask of PEER_CONNECTION_FLAG_ */
	time_t lastactivity;             /**< Time of last transmit. */
	guint destroy_timeout;
	OscarDisconnectReason disconnect_reason;
	char *error_message;

	/**
	 * A pointer to either an OdcFrame or an OftFrame.
	 */
	gpointer frame;

	/**
	 * This is only used when the peer connection is being established.
	 */
	PurpleProxyConnectData *client_connect_data;
	PurpleProxyConnectData *verified_connect_data;

	/**
	 * This is only used when the peer connection is being established.
	 */
	PurpleNetworkListenData *listen_data;


	/**
	 * This is only used when the peer connection is being established.
	 */
	guint connect_timeout_timer;

	/**
	 * This is only used while the remote user is attempting to
	 * connect to us.
	 */
	int listenerfd;

	int fd;
	guint8 header[6];
	gssize header_received;
	guint8 proxy_header[12];
	gssize proxy_header_received;
	ByteStream buffer_incoming;
	PurpleCircBuffer *buffer_outgoing;
	guint watcher_incoming;
	guint watcher_outgoing;

	/**
	 * IP address of the proxy server, if applicable.
	 */
	gchar *proxyip;

	/**
	 * IP address of the remote user from THEIR point of view.
	 */
	gchar *clientip;

	/**
	 * IP address of the remote user from the oscar server's
	 * point of view.
	 */
	gchar *verifiedip;

	guint16 port;
	gboolean use_proxy;

	/**
	 * Checksumming
	 */
	ChecksumData *checksum_data;

	/* TODOFT */
	PurpleXfer *xfer;
	OftFrame xferdata;
	guint sending_data_timer;
};

/*
 * For all peer connections
 */

/**
 * Create a new PeerConnection structure and initialize it with some
 * sane defaults.
 *
 * @param type The type of the peer connection.  One of
 *        OSCAR_CAPABILITY_DIRECTIM or OSCAR_CAPABILITY_SENDFILE.
 */
PeerConnection *peer_connection_new(OscarData *od, guint64 type, const char *bn);

void peer_connection_destroy(PeerConnection *conn, OscarDisconnectReason reason, const gchar *error_message);
void peer_connection_schedule_destroy(PeerConnection *conn, OscarDisconnectReason reason, const gchar *error_message);
PeerConnection *peer_connection_find_by_type(OscarData *od, const char *bn, guint64 type);
PeerConnection *peer_connection_find_by_cookie(OscarData *od, const char *bn, const guchar *cookie);

void peer_connection_listen_cb(gpointer data, gint source, PurpleInputCondition cond);
void peer_connection_recv_cb(gpointer data, gint source, PurpleInputCondition cond);
void peer_connection_send(PeerConnection *conn, ByteStream *bs);

void peer_connection_trynext(PeerConnection *conn);
void peer_connection_finalize_connection(PeerConnection *conn);
void peer_connection_propose(OscarData *od, guint64 type, const char *bn);
void peer_connection_got_proposition(OscarData *od, const gchar *bn, const gchar *message, IcbmArgsCh2 *args);

/*
 * For ODC
 */
void peer_odc_close(PeerConnection *conn);
void peer_odc_recv_frame(PeerConnection *conn, ByteStream *bs);
void peer_odc_send_cookie(PeerConnection *conn);
void peer_odc_send_typing(PeerConnection *conn, PurpleTypingState typing);
void peer_odc_send_im(PeerConnection *conn, const char *msg, int len, int encoding, gboolean autoreply);

/*
 * For OFT
 */
void peer_oft_close(PeerConnection *conn);
void peer_oft_recv_frame(PeerConnection *conn, ByteStream *bs);
void peer_oft_send_prompt(PeerConnection *conn);
void peer_oft_checksum_destroy(ChecksumData *checksum_data);

/* Xfer callbacks for receiving a file */
void peer_oft_recvcb_init(PurpleXfer *xfer);
void peer_oft_recvcb_end(PurpleXfer *xfer);
void peer_oft_recvcb_ack_recv(PurpleXfer *xfer, const guchar *buffer, size_t size);

/* Xfer callbacks for sending a file */
void peer_oft_sendcb_init(PurpleXfer *xfer);
void peer_oft_sendcb_ack(PurpleXfer *xfer, const guchar *buffer, size_t size);

/* Xfer callbacks for both sending and receiving */
void peer_oft_cb_generic_cancel(PurpleXfer *xfer);

/*
 * For peer proxying
 */
void peer_proxy_connection_established_cb(gpointer data, gint source, const gchar *error_message);

#endif /* _PEER_H_ */