示例#1
0
文件: slplink.c 项目: Lilitana/Pidgin
static MsnSlpMessage *
init_first_msg(MsnSlpLink *slplink, MsnP2PInfo *info)
{
	MsnSlpMessage *slpmsg;
	guint32 session_id;

	slpmsg = msn_slpmsg_new(slplink, NULL);
	slpmsg->id = msn_p2p_info_get_id(info);
	session_id = msn_p2p_info_get_session_id(info);
	slpmsg->size = msn_p2p_info_get_total_size(info);
	msn_p2p_info_init_first(slpmsg->p2p_info, info);

	if (session_id)
	{
		slpmsg->slpcall = msn_slplink_find_slp_call_with_session_id(slplink, session_id);
		if (slpmsg->slpcall != NULL)
		{
			if (msn_p2p_msg_is_data(info))
			{
				PurpleXfer *xfer = slpmsg->slpcall->xfer;
				if (xfer != NULL)
				{
					slpmsg->ft = TRUE;
					slpmsg->slpcall->xfer_msg = slpmsg;

					purple_xfer_ref(xfer);
					purple_xfer_start(xfer,	-1, NULL, 0);

					if (xfer->data == NULL) {
						purple_xfer_unref(xfer);
						msn_slpmsg_destroy(slpmsg);
						g_return_val_if_reached(NULL);
					} else {
						purple_xfer_unref(xfer);
					}
				}
			}
		}
	}
	if (!slpmsg->ft && slpmsg->size)
	{
		slpmsg->buffer = g_try_malloc(slpmsg->size);
		if (slpmsg->buffer == NULL)
		{
			purple_debug_error("msn", "Failed to allocate buffer for slpmsg\n");
			msn_slpmsg_destroy(slpmsg);
			return NULL;
		}
	}

	return slpmsg;
}
示例#2
0
static void
msn_slplink_send_ack(MsnSlpLink *slplink, MsnSlpHeader *header)
{
	MsnSlpMessage *slpmsg = msn_slplink_create_ack(slplink, header);

	msn_slplink_send_slpmsg(slplink, slpmsg);
	msn_slpmsg_destroy(slpmsg);
}
示例#3
0
文件: slplink.c 项目: Lilitana/Pidgin
static void
msn_slplink_send_ack(MsnSlpLink *slplink, MsnP2PInfo *info)
{
	MsnSlpMessage *slpmsg = msn_slpmsg_ack_new(slplink, info);

	msn_slplink_send_slpmsg(slplink, slpmsg);
	msn_slpmsg_destroy(slpmsg);
}
示例#4
0
文件: slpcall.c 项目: bf4/pidgin-mac
void
msn_slp_call_destroy(MsnSlpCall *slpcall)
{
	GList *e;
	MsnSession *session;

#ifdef MSN_DEBUG_SLPCALL
	purple_debug_info("msn", "slpcall_destroy: slpcall(%p)\n", slpcall);
#endif

	g_return_if_fail(slpcall != NULL);

	if (slpcall->timer)
		purple_timeout_remove(slpcall->timer);

	if (slpcall->id != NULL)
		g_free(slpcall->id);

	if (slpcall->branch != NULL)
		g_free(slpcall->branch);

	if (slpcall->data_info != NULL)
		g_free(slpcall->data_info);

	for (e = slpcall->slplink->slp_msgs; e != NULL; )
	{
		MsnSlpMessage *slpmsg = e->data;
		e = e->next;

#ifdef MSN_DEBUG_SLPCALL_VERBOSE
		purple_debug_info("msn", "slpcall_destroy: trying slpmsg(%p)\n",
						slpmsg);
#endif

		if (slpmsg->slpcall == slpcall)
		{
			msn_slpmsg_destroy(slpmsg);
		}
	}

	session = slpcall->slplink->session;

	msn_slplink_remove_slpcall(slpcall->slplink, slpcall);

	if (slpcall->end_cb != NULL)
		slpcall->end_cb(slpcall, session);

	if (slpcall->xfer != NULL) {
		slpcall->xfer->data = NULL;
		purple_xfer_unref(slpcall->xfer);
	}

	g_free(slpcall);
}
示例#5
0
文件: slplink.c 项目: Lilitana/Pidgin
static void
process_complete_msg(MsnSlpLink *slplink, MsnSlpMessage *slpmsg, MsnP2PInfo *info)
{
	MsnSlpCall *slpcall;

	slpcall = msn_slp_process_msg(slplink, slpmsg);

	if (slpcall == NULL) {
		msn_slpmsg_destroy(slpmsg);
		return;
	}

	purple_debug_info("msn", "msn_slplink_process_msg: slpmsg complete\n");

	if (msn_p2p_info_require_ack(slpmsg->p2p_info))
	{
		/* Release all the messages and send the ACK */

		if (slpcall->wait_for_socket) {
			/*
			 * Save ack for later because we have to send
			 * a 200 OK message to the previous direct connect
			 * invitation before ACK but the listening socket isn't
			 * created yet.
			 */
			purple_debug_info("msn", "msn_slplink_process_msg: save ACK\n");

			slpcall->slplink->dc->prev_ack = msn_slpmsg_ack_new(slplink, info);
		} else if (!slpcall->wasted) {
			purple_debug_info("msn", "msn_slplink_process_msg: send ACK\n");

			msn_slplink_send_ack(slplink, info);
			msn_slplink_send_queued_slpmsgs(slplink);
		}
	}

	msn_slpmsg_destroy(slpmsg);

	if (!slpcall->wait_for_socket && slpcall->wasted)
		msn_slpcall_destroy(slpcall);
}
示例#6
0
void
msn_dc_send_ok(MsnDirectConn *dc)
{
	if (purple_debug_is_verbose())
		purple_debug_info("msn", "msn_dc_send_ok %p\n", dc);

	g_return_if_fail(dc != NULL);

	msn_slp_send_ok(dc->slpcall, dc->slpcall->branch,
		"application/x-msnmsgr-transrespbody", dc->msg_body);
	g_free(dc->msg_body);
	dc->msg_body = NULL;

	msn_slplink_send_slpmsg(dc->slpcall->slplink, dc->prev_ack);
	msn_slpmsg_destroy(dc->prev_ack);
	dc->prev_ack = NULL;
	msn_slplink_send_queued_slpmsgs(dc->slpcall->slplink);
}
示例#7
0
static void
msn_slplink_send_ack(MsnSlpLink *slplink, MsnMessage *msg)
{
	MsnSlpMessage *slpmsg;

	slpmsg = msn_slpmsg_new(slplink);

	slpmsg->session_id = msg->msnslp_header.session_id;
	slpmsg->size       = msg->msnslp_header.total_size;
	slpmsg->flags      = 0x02;
	slpmsg->ack_id     = msg->msnslp_header.id;
	slpmsg->ack_sub_id = msg->msnslp_header.ack_id;
	slpmsg->ack_size   = msg->msnslp_header.total_size;
	slpmsg->info = "SLP ACK";

	msn_slplink_send_slpmsg(slplink, slpmsg);
	msn_slpmsg_destroy(slpmsg);
}
示例#8
0
void
msn_slplink_process_msg(MsnSlpLink *slplink, MsnSlpHeader *header, const char *data, gsize len)
{
	MsnSlpMessage *slpmsg;
	guint64 offset;
	PurpleXfer *xfer = NULL;

	if (header->total_size < header->length)
	{
		purple_debug_error("msn", "This can't be good\n");
		g_return_if_reached();
	}

	offset = header->offset;

	if (offset == 0)
	{
		slpmsg = msn_slpmsg_new(slplink);
		slpmsg->id = header->id;
		slpmsg->session_id = header->session_id;
		slpmsg->size = header->total_size;
		slpmsg->flags = header->flags;

		if (slpmsg->session_id)
		{
			if (slpmsg->slpcall == NULL)
				slpmsg->slpcall = msn_slplink_find_slp_call_with_session_id(slplink, slpmsg->session_id);

			if (slpmsg->slpcall != NULL)
			{
				if (slpmsg->flags == 0x20 ||
				    slpmsg->flags == 0x1000020 || slpmsg->flags == 0x1000030)
				{
					xfer = slpmsg->slpcall->xfer;
					if (xfer != NULL)
					{
						slpmsg->ft = TRUE;
						slpmsg->slpcall->xfer_msg = slpmsg;

						purple_xfer_ref(xfer);
						purple_xfer_start(xfer,	-1, NULL, 0);

						if (xfer->data == NULL) {
							purple_xfer_unref(xfer);
							msn_slpmsg_destroy(slpmsg);
							g_return_if_reached();
						} else {
							purple_xfer_unref(xfer);
						}
					}
				}
			}
		}
		if (!slpmsg->ft && slpmsg->size)
		{
			slpmsg->buffer = g_try_malloc(slpmsg->size);
			if (slpmsg->buffer == NULL)
			{
				purple_debug_error("msn", "Failed to allocate buffer for slpmsg\n");
				msn_slpmsg_destroy(slpmsg);
				return;
			}
		}
	}
	else
	{
		slpmsg = msn_slplink_message_find(slplink, header->session_id, header->id);
		if (slpmsg == NULL)
		{
			/* Probably the transfer was canceled */
			purple_debug_error("msn", "Couldn't find slpmsg\n");
			return;
		}
	}

	if (slpmsg->ft)
	{
		xfer = slpmsg->slpcall->xfer;
		slpmsg->slpcall->u.incoming_data =
				g_byte_array_append(slpmsg->slpcall->u.incoming_data, (const guchar *)data, len);
		purple_xfer_prpl_ready(xfer);
	}
	else if (slpmsg->size && slpmsg->buffer)
	{
		if (G_MAXSIZE - len < offset || (offset + len) > slpmsg->size || slpmsg->offset != offset)
		{
			purple_debug_error("msn",
				"Oversized slpmsg - msgsize=%lld offset=%" G_GUINT64_FORMAT " len=%" G_GSIZE_FORMAT "\n",
				slpmsg->size, offset, len);
			g_return_if_reached();
		} else {
			memcpy(slpmsg->buffer + offset, data, len);
			slpmsg->offset += len;
		}
	}

	if ((slpmsg->flags == 0x20 ||
	     slpmsg->flags == 0x1000020 || slpmsg->flags == 0x1000030) &&
		(slpmsg->slpcall != NULL))
	{
		slpmsg->slpcall->progress = TRUE;

		if (slpmsg->slpcall->progress_cb != NULL)
		{
			slpmsg->slpcall->progress_cb(slpmsg->slpcall, slpmsg->size,
										 len, offset);
		}
	}

#if 0
	if (slpmsg->buffer == NULL)
		return;
#endif

	if (header->offset + header->length >= header->total_size)
	{
		/* All the pieces of the slpmsg have been received */
		MsnSlpCall *slpcall;

		slpcall = msn_slp_process_msg(slplink, slpmsg);

		if (slpcall == NULL) {
			msn_slpmsg_destroy(slpmsg);
			return;
		}

		purple_debug_info("msn", "msn_slplink_process_msg: slpmsg complete\n");

		if (/* !slpcall->wasted && */ slpmsg->flags == 0x100)
		{
#if 0
			MsnDirectConn *directconn;

			directconn = slplink->directconn;
			if (!directconn->acked)
				msn_directconn_send_handshake(directconn);
#endif
		}
		else if (slpmsg->flags == 0x00 || slpmsg->flags == 0x1000000 ||
		         slpmsg->flags == 0x20 || slpmsg->flags == 0x1000020 ||
		         slpmsg->flags == 0x1000030)
		{
			/* Release all the messages and send the ACK */

			if (slpcall->wait_for_socket) {
				/*
				 * Save ack for later because we have to send
				 * a 200 OK message to the previous direct connect
				 * invitation before ACK but the listening socket isn't
				 * created yet.
				 */
				purple_debug_info("msn", "msn_slplink_process_msg: save ACK\n");

				slpcall->slplink->dc->prev_ack = msn_slplink_create_ack(slplink, header);
			} else if (!slpcall->wasted) {
				purple_debug_info("msn", "msn_slplink_process_msg: send ACK\n");

				msn_slplink_send_ack(slplink, header);
				msn_slplink_send_queued_slpmsgs(slplink);
			}
		}

		msn_slpmsg_destroy(slpmsg);

		if (!slpcall->wait_for_socket && slpcall->wasted)
			msn_slpcall_destroy(slpcall);
	}
}
示例#9
0
void
msn_dc_destroy(MsnDirectConn *dc)
{
	MsnSlpLink *slplink;

	if (purple_debug_is_verbose())
		purple_debug_info("msn", "msn_dc_destroy %p\n", dc);

	g_return_if_fail(dc != NULL);

	if (dc->slpcall != NULL)
		dc->slpcall->wait_for_socket = FALSE;

	slplink = dc->slplink;
	if (slplink) {
		slplink->dc = NULL;
		if (slplink->swboard == NULL)
			msn_slplink_unref(slplink);
	}

	g_free(dc->msg_body);

	if (dc->prev_ack) {
		msn_slpmsg_destroy(dc->prev_ack);
	}

	if (dc->listen_data != NULL) {
		purple_network_listen_cancel(dc->listen_data);
	}

	if (dc->connect_data != NULL) {
		purple_proxy_connect_cancel(dc->connect_data);
	}

	if (dc->listenfd != -1) {
		purple_network_remove_port_mapping(dc->listenfd);
		close(dc->listenfd);
	}

	if (dc->listenfd_handle != 0) {
		purple_input_remove(dc->listenfd_handle);
	}

	if (dc->connect_timeout_handle != 0) {
		purple_timeout_remove(dc->connect_timeout_handle);
	}

	if (dc->fd != -1) {
		close(dc->fd);
	}

	if (dc->send_handle != 0) {
		purple_input_remove(dc->send_handle);
	}

	if (dc->recv_handle != 0) {
		purple_input_remove(dc->recv_handle);
	}

	g_free(dc->in_buffer);

	if (dc->out_queue != NULL) {
		while (!g_queue_is_empty(dc->out_queue))
			msn_dc_destroy_packet( g_queue_pop_head(dc->out_queue) );

		g_queue_free(dc->out_queue);
	}

	g_free(dc->ext_ip);

	if (dc->timeout_handle != 0) {
		purple_timeout_remove(dc->timeout_handle);
	}

	g_free(dc);
}
示例#10
0
文件: slplink.c 项目: bf4/pidgin-mac
void
msn_slplink_process_msg(MsnSlpLink *slplink, MsnMessage *msg)
{
	MsnSlpMessage *slpmsg;
	const char *data;
	gsize offset;
	gsize len;

#ifdef MSN_DEBUG_SLP
	msn_slpmsg_show(msg);
#endif

#ifdef MSN_DEBUG_SLP_FILES
	debug_msg_to_file(msg, FALSE);
#endif

	if (msg->msnslp_header.total_size < msg->msnslp_header.length)
	{
		purple_debug_error("msn", "This can't be good\n");
		g_return_if_reached();
	}

	slpmsg = NULL;
	data = msn_message_get_bin_data(msg, &len);

	/*
		OVERHEAD!
		if (msg->msnslp_header.length < msg->msnslp_header.total_size)
	 */

	offset = msg->msnslp_header.offset;

	if (offset == 0)
	{
		slpmsg = msn_slpmsg_new(slplink);
		slpmsg->id = msg->msnslp_header.id;
		slpmsg->session_id = msg->msnslp_header.session_id;
		slpmsg->size = msg->msnslp_header.total_size;
		slpmsg->flags = msg->msnslp_header.flags;

		if (slpmsg->session_id)
		{
			if (slpmsg->slpcall == NULL)
				slpmsg->slpcall = msn_slplink_find_slp_call_with_session_id(slplink, slpmsg->session_id);

			if (slpmsg->slpcall != NULL)
			{
				if (slpmsg->flags == 0x20 || slpmsg->flags == 0x1000030)
				{
					PurpleXfer *xfer;

					xfer = slpmsg->slpcall->xfer;

					if (xfer != NULL)
					{
						purple_xfer_ref(xfer);
						purple_xfer_start(xfer,	0, NULL, 0);

						if (xfer->data == NULL) {
							purple_xfer_unref(xfer);
							return;
						} else {
							purple_xfer_unref(xfer);
							slpmsg->fp = xfer->dest_fp;
							xfer->dest_fp = NULL; /* Disable double fclose() */
						}
					}
				}
			}
		}
		if (!slpmsg->fp && slpmsg->size)
		{
			slpmsg->buffer = g_try_malloc(slpmsg->size);
			if (slpmsg->buffer == NULL)
			{
				purple_debug_error("msn", "Failed to allocate buffer for slpmsg\n");
				return;
			}
		}
	}
	else
	{
		slpmsg = msn_slplink_message_find(slplink, msg->msnslp_header.session_id, msg->msnslp_header.id);
	}

	if (slpmsg == NULL)
	{
		/* Probably the transfer was canceled */
		purple_debug_error("msn", "Couldn't find slpmsg\n");
		return;
	}

	if (slpmsg->fp)
	{
		/* fseek(slpmsg->fp, offset, SEEK_SET); */
		len = fwrite(data, 1, len, slpmsg->fp);
	}
	else if (slpmsg->size)
	{
		if (G_MAXSIZE - len < offset || (offset + len) > slpmsg->size)
		{
			purple_debug_error("msn", "Oversized slpmsg\n");
			g_return_if_reached();
		}
		else
			memcpy(slpmsg->buffer + offset, data, len);
	}

	if ((slpmsg->flags == 0x20 || slpmsg->flags == 0x1000030) &&
		(slpmsg->slpcall != NULL))
	{
		slpmsg->slpcall->progress = TRUE;

		if (slpmsg->slpcall->progress_cb != NULL)
		{
			slpmsg->slpcall->progress_cb(slpmsg->slpcall, slpmsg->size,
										 len, offset);
		}
	}

#if 0
	if (slpmsg->buffer == NULL)
		return;
#endif

	if (msg->msnslp_header.offset + msg->msnslp_header.length
		>= msg->msnslp_header.total_size)
	{
		/* All the pieces of the slpmsg have been received */
		MsnSlpCall *slpcall;

		slpcall = msn_slp_process_msg(slplink, slpmsg);

		if (slpmsg->flags == 0x100)
		{
			MsnDirectConn *directconn;

			directconn = slplink->directconn;

			if (!directconn->acked)
				msn_directconn_send_handshake(directconn);
		}
		else if (slpmsg->flags == 0x0 || slpmsg->flags == 0x20 ||
				 slpmsg->flags == 0x1000030)
		{
			/* Release all the messages and send the ACK */

			msn_slplink_send_ack(slplink, msg);
			msn_slplink_unleash(slplink);
		}

		msn_slpmsg_destroy(slpmsg);

		if (slpcall != NULL && slpcall->wasted)
			msn_slp_call_destroy(slpcall);
	}
}