⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 peer.c

📁 Linux下的多协议即时通讯程序源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	/* Cancel this timer.  It'll be added again, if needed. */	return FALSE;}/** * Try to establish the given PeerConnection using a defined * sequence of steps. */voidpeer_connection_trynext(PeerConnection *conn){	PurpleAccount *account;	account = purple_connection_get_account(conn->od->gc);	/*	 * Close any remnants of a previous failed connection attempt.	 */	peer_connection_close(conn);	/*	 * 1. Attempt to connect to the remote user using their verifiedip and clientip.	 *    We try these at the same time and use whichever succeeds first, so we don't	 *    have to wait for a timeout.	 */	if (!(conn->flags & PEER_CONNECTION_FLAG_TRIED_DIRECT) &&		(conn->verifiedip != NULL) && (conn->port != 0) && (!conn->use_proxy))	{		conn->flags |= PEER_CONNECTION_FLAG_TRIED_DIRECT;		if (conn->type == OSCAR_CAPABILITY_DIRECTIM)		{			gchar *tmp;			PurpleConversation *conv;			tmp = g_strdup_printf(_("Attempting to connect to %s:%hu."),					conn->verifiedip, conn->port);			conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, conn->sn);			purple_conversation_write(conv, NULL, tmp,					PURPLE_MESSAGE_SYSTEM, time(NULL));			g_free(tmp);		}		conn->verified_connect_data = purple_proxy_connect(NULL, account,				conn->verifiedip, conn->port,				peer_connection_verified_established_cb, conn);		if ((conn->verifiedip == NULL) ||			strcmp(conn->verifiedip, conn->clientip))		{			conn->client_connect_data = purple_proxy_connect(NULL, account,					conn->clientip, conn->port,					peer_connection_client_established_cb, conn);		}		if ((conn->verified_connect_data != NULL) ||			(conn->client_connect_data != NULL))		{			/* Connecting... */			conn->connect_timeout_timer = purple_timeout_add(5000,					peer_connection_tooktoolong, conn);			return;		}	}	/*	 * 2. Attempt to have the remote user connect to us (using both	 *    our verifiedip and our clientip).	 */	if (!(conn->flags & PEER_CONNECTION_FLAG_TRIED_INCOMING) &&		(!conn->use_proxy))	{		conn->flags |= PEER_CONNECTION_FLAG_TRIED_INCOMING;		/*		 * Remote user is connecting to us, so we'll need to verify		 * that the user who connected is our friend.		 */		conn->flags |= PEER_CONNECTION_FLAG_IS_INCOMING;		conn->listen_data = purple_network_listen_range(5190, 5290, SOCK_STREAM,				peer_connection_establish_listener_cb, conn);		if (conn->listen_data != NULL)		{			/* Opening listener socket... */			return;		}	}	/*	 * 3. Attempt to have both users connect to an intermediate proxy	 *    server.	 */	if (!(conn->flags & PEER_CONNECTION_FLAG_TRIED_PROXY))	{		conn->flags |= PEER_CONNECTION_FLAG_TRIED_PROXY;		/*		 * If we initiate the proxy connection, then the remote user		 * could be anyone, so we need to verify that the user who		 * connected is our friend.		 */		if (!conn->use_proxy)			conn->flags |= PEER_CONNECTION_FLAG_IS_INCOMING;		if (conn->type == OSCAR_CAPABILITY_DIRECTIM)		{			gchar *tmp;			PurpleConversation *conv;			tmp = g_strdup_printf(_("Attempting to connect via proxy server."));			conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, conn->sn);			purple_conversation_write(conv, NULL, tmp,					PURPLE_MESSAGE_SYSTEM, time(NULL));			g_free(tmp);		}		conn->verified_connect_data = purple_proxy_connect(NULL, account,				(conn->proxyip != NULL) ? conn->proxyip : PEER_PROXY_SERVER,				PEER_PROXY_PORT,				peer_proxy_connection_established_cb, conn);		if (conn->verified_connect_data != NULL)		{			/* Connecting... */			return;		}	}	/* Give up! */	peer_connection_destroy(conn, OSCAR_DISCONNECT_COULD_NOT_CONNECT, NULL);}/** * Initiate a peer connection with someone. */voidpeer_connection_propose(OscarData *od, OscarCapability type, const char *sn){	PeerConnection *conn;	if (type == OSCAR_CAPABILITY_DIRECTIM)	{		conn = peer_connection_find_by_type(od, sn, type);		if (conn != NULL)		{			if (conn->ready)			{				PurpleAccount *account;				PurpleConversation *conv;				purple_debug_info("oscar", "Already have a direct IM "						"session with %s.\n", sn);				account = purple_connection_get_account(od->gc);				conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM,						sn, account);				if (conv != NULL)					purple_conversation_present(conv);				return;			}			/* Cancel the old connection and try again */			peer_connection_destroy(conn, OSCAR_DISCONNECT_RETRYING, NULL);		}	}	conn = peer_connection_new(od, type, sn);	conn->flags |= PEER_CONNECTION_FLAG_INITIATED_BY_ME;	conn->flags |= PEER_CONNECTION_FLAG_APPROVED;	aim_icbm_makecookie(conn->cookie);	peer_connection_trynext(conn);}/** * Someone else wants to establish a peer connection with us, * and we said yes. */static voidpeer_connection_got_proposition_yes_cb(gpointer data, gint id){	PeerConnection *conn;	conn = data;	conn->flags |= PEER_CONNECTION_FLAG_APPROVED;	peer_connection_trynext(conn);}/** * Someone else wants to establish a peer connection with us, * and we said no. * * "Well, one time my friend asked me if I wanted to play the *  piccolo.  But I said no." */static voidpeer_connection_got_proposition_no_cb(gpointer data, gint id){	PeerConnection *conn;	conn = data;	aim_im_denytransfer(conn->od, conn->sn, conn->cookie,			AIM_TRANSFER_DENY_DECLINE);	peer_connection_destroy(conn, OSCAR_DISCONNECT_LOCAL_CLOSED, NULL);}/** * Someone else wants to establish a peer connection with us. */voidpeer_connection_got_proposition(OscarData *od, const gchar *sn, const gchar *message, IcbmArgsCh2 *args){	PurpleConnection *gc;	PurpleAccount *account;	PeerConnection *conn;	gchar *buf;	gc = od->gc;	account = purple_connection_get_account(gc);	/*	 * If we have a connection with this same cookie then they are	 * probably just telling us they weren't able to connect to us	 * and we should try connecting to them, instead.  Or they want	 * to go through a proxy.	 */	conn = peer_connection_find_by_cookie(od, sn, args->cookie);	if ((conn != NULL) && (conn->type == args->type))	{		purple_debug_info("oscar", "Remote user wants to try a "				"different connection method\n");		g_free(conn->proxyip);		g_free(conn->clientip);		g_free(conn->verifiedip);		if (args->use_proxy)			conn->proxyip = g_strdup(args->proxyip);		else			conn->proxyip = NULL;		conn->verifiedip = g_strdup(args->verifiedip);		conn->clientip = g_strdup(args->clientip);		conn->port = args->port;		conn->use_proxy |= args->use_proxy;		conn->lastrequestnumber++;		peer_connection_trynext(conn);		return;	}	/* If this is a direct IM, then close any existing session */	if (args->type == OSCAR_CAPABILITY_DIRECTIM)	{		conn = peer_connection_find_by_type(od, sn, args->type);		if (conn != NULL)		{			/* Close the old direct IM and start a new one */			purple_debug_info("oscar", "Received new direct IM request "				"from %s.  Destroying old connection.\n", sn);			peer_connection_destroy(conn, OSCAR_DISCONNECT_REMOTE_CLOSED, NULL);		}	}	/* Check for proper arguments */	if (args->type == OSCAR_CAPABILITY_SENDFILE)	{		if ((args->info.sendfile.filename == NULL) ||			(args->info.sendfile.totsize == 0) ||			(args->info.sendfile.totfiles == 0))		{			purple_debug_warning("oscar",					"%s tried to send you a file with incomplete "					"information.\n", sn);			return;		}	}	conn = peer_connection_new(od, args->type, sn);	memcpy(conn->cookie, args->cookie, 8);	if (args->use_proxy)		conn->proxyip = g_strdup(args->proxyip);	conn->clientip = g_strdup(args->clientip);	conn->verifiedip = g_strdup(args->verifiedip);	conn->port = args->port;	conn->use_proxy |= args->use_proxy;	conn->lastrequestnumber++;	if (args->type == OSCAR_CAPABILITY_DIRECTIM)	{		buf = g_strdup_printf(_("%s has just asked to directly connect to %s"),				sn, purple_account_get_username(account));		purple_request_action(conn, NULL, buf,						_("This requires a direct connection between "						  "the two computers and is necessary for IM "						  "Images.  Because your IP address will be "						  "revealed, this may be considered a privacy "						  "risk."),						PURPLE_DEFAULT_ACTION_NONE,						account, sn, NULL,						conn, 2,						_("_Connect"), G_CALLBACK(peer_connection_got_proposition_yes_cb),						_("Cancel"), G_CALLBACK(peer_connection_got_proposition_no_cb));	}	else if (args->type == OSCAR_CAPABILITY_SENDFILE)	{		gchar *filename;		conn->xfer = purple_xfer_new(account, PURPLE_XFER_RECEIVE, sn);		if (conn->xfer)		{			conn->xfer->data = conn;			purple_xfer_ref(conn->xfer);			purple_xfer_set_size(conn->xfer, args->info.sendfile.totsize);			/* Set the file name */			if (g_utf8_validate(args->info.sendfile.filename, -1, NULL))				filename = g_strdup(args->info.sendfile.filename);			else				filename = purple_utf8_salvage(args->info.sendfile.filename);			if (args->info.sendfile.subtype == AIM_OFT_SUBTYPE_SEND_DIR)			{				/*				 * If they are sending us a directory then the last character				 * of the file name will be an asterisk.  We don't want to				 * save stuff to a directory named "*" so we remove the				 * asterisk from the file name.				 */				char *tmp = strrchr(filename, '\\');				if ((tmp != NULL) && (tmp[1] == '*'))					tmp[0] = '\0';			}			purple_xfer_set_filename(conn->xfer, filename);			g_free(filename);			/*			 * Set the message, unless this is the dummy message from an			 * ICQ client or an empty message from an AIM client.			 * TODO: Maybe we should strip HTML and then see if strlen>0?			 */			if ((message != NULL) &&				(g_ascii_strncasecmp(message, "<ICQ_COOL_FT>", 13) != 0) &&				(g_ascii_strcasecmp(message, "<HTML>") != 0))			{				purple_xfer_set_message(conn->xfer, message);			}			/* Setup our I/O op functions */			purple_xfer_set_init_fnc(conn->xfer, peer_oft_recvcb_init);			purple_xfer_set_end_fnc(conn->xfer, peer_oft_recvcb_end);			purple_xfer_set_request_denied_fnc(conn->xfer, peer_oft_cb_generic_cancel);			purple_xfer_set_cancel_recv_fnc(conn->xfer, peer_oft_cb_generic_cancel);			purple_xfer_set_ack_fnc(conn->xfer, peer_oft_recvcb_ack_recv);			/* Now perform the request */			purple_xfer_request(conn->xfer);		}	}}/*******************************************************************//* End code for establishing a peer connection                     *//*******************************************************************/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -