comparison libpurple/protocols/oscar/flap_connection.c @ 24651:ea70a446dde4

First pass at adding SSL connections to OSCAR. Both AIM and ICQ can connect. Three FLAP servers seem to dislike SSL: (15:39:46) nss: Handshake failed (-5961) (15:39:46) oscar: unable to connect to FLAP server of type 0x0018 (15:39:46) nss: Handshake failed (-5961) (15:39:46) oscar: unable to connect to FLAP server of type 0x000d (15:39:46) nss: Handshake failed (-5961) (15:39:46) oscar: unable to connect to FLAP server of type 0x0010 As a consequence, neither buddy icons nor chats work currently.
author Paul Aurich <paul@darkrain42.org>
date Wed, 10 Dec 2008 23:41:28 +0000
parents fef608a31864
children c6772d61af1f
comparison
equal deleted inserted replaced
24626:2f84f888d3db 24651:ea70a446dde4
360 if (conn->type == SNAC_FAMILY_LOCATE) 360 if (conn->type == SNAC_FAMILY_LOCATE)
361 flap_connection_send_close(od, conn); 361 flap_connection_send_close(od, conn);
362 362
363 close(conn->fd); 363 close(conn->fd);
364 conn->fd = -1; 364 conn->fd = -1;
365 }
366
367 if (conn->gsc != NULL)
368 {
369 if (conn->type == SNAC_FAMILY_LOCATE)
370 flap_connection_send_close(od, conn);
371
372 purple_ssl_close(conn->gsc);
373 conn->gsc = NULL;
365 } 374 }
366 375
367 if (conn->watcher_incoming != 0) 376 if (conn->watcher_incoming != 0)
368 { 377 {
369 purple_input_remove(conn->watcher_incoming); 378 purple_input_remove(conn->watcher_incoming);
842 /** 851 /**
843 * Read in all available data on the socket for a given connection. 852 * Read in all available data on the socket for a given connection.
844 * All complete FLAPs handled immedate after they're received. 853 * All complete FLAPs handled immedate after they're received.
845 * Incomplete FLAP data is stored locally and appended to the next 854 * Incomplete FLAP data is stored locally and appended to the next
846 * time this callback is triggered. 855 * time this callback is triggered.
847 */ 856 *
848 void 857 * This is called by flap_connection_recv_cb and
849 flap_connection_recv_cb(gpointer data, gint source, PurpleInputCondition cond) 858 * flap_connection_recv_cb_ssl for unencrypted/encrypted connections.
850 { 859 */
851 FlapConnection *conn; 860 static void
861 flap_connection_recv(FlapConnection *conn)
862 {
863 gpointer buf;
864 gsize buflen;
852 gssize read; 865 gssize read;
853
854 conn = data;
855 866
856 /* Read data until we run out of data and break out of the loop */ 867 /* Read data until we run out of data and break out of the loop */
857 while (TRUE) 868 while (TRUE)
858 { 869 {
859 /* Start reading a new FLAP */ 870 /* Start reading a new FLAP */
860 if (conn->buffer_incoming.data.data == NULL) 871 if (conn->buffer_incoming.data.data == NULL)
861 { 872 {
873 buf = conn->header + conn->header_received;
874 buflen = 6 - conn->header_received;
875
862 /* Read the first 6 bytes (the FLAP header) */ 876 /* Read the first 6 bytes (the FLAP header) */
863 read = recv(conn->fd, conn->header + conn->header_received, 877 if (conn->gsc)
864 6 - conn->header_received, 0); 878 read = purple_ssl_read(conn->gsc, buf, buflen);
879 else
880 read = recv(conn->fd, buf, buflen, 0);
865 881
866 /* Check if the FLAP server closed the connection */ 882 /* Check if the FLAP server closed the connection */
867 if (read == 0) 883 if (read == 0)
868 { 884 {
869 flap_connection_schedule_destroy(conn, 885 flap_connection_schedule_destroy(conn,
916 conn->buffer_incoming.data.len = aimutil_get16(&conn->header[4]); 932 conn->buffer_incoming.data.len = aimutil_get16(&conn->header[4]);
917 conn->buffer_incoming.data.data = g_new(guint8, conn->buffer_incoming.data.len); 933 conn->buffer_incoming.data.data = g_new(guint8, conn->buffer_incoming.data.len);
918 conn->buffer_incoming.data.offset = 0; 934 conn->buffer_incoming.data.offset = 0;
919 } 935 }
920 936
921 if (conn->buffer_incoming.data.len - conn->buffer_incoming.data.offset) 937 buflen = conn->buffer_incoming.data.len - conn->buffer_incoming.data.offset;
938 if (buflen)
922 { 939 {
940 buf = &conn->buffer_incoming.data.data[conn->buffer_incoming.data.offset];
923 /* Read data into the temporary FlapFrame until it is complete */ 941 /* Read data into the temporary FlapFrame until it is complete */
924 read = recv(conn->fd, 942 if (conn->gsc)
925 &conn->buffer_incoming.data.data[conn->buffer_incoming.data.offset], 943 read = purple_ssl_read(conn->gsc, buf, buflen);
926 conn->buffer_incoming.data.len - conn->buffer_incoming.data.offset, 944 else
927 0); 945 read = recv(conn->fd, buf, buflen, 0);
928 946
929 /* Check if the FLAP server closed the connection */ 947 /* Check if the FLAP server closed the connection */
930 if (read == 0) 948 if (read == 0)
931 { 949 {
932 flap_connection_schedule_destroy(conn, 950 flap_connection_schedule_destroy(conn,
962 980
963 conn->header_received = 0; 981 conn->header_received = 0;
964 } 982 }
965 } 983 }
966 984
985 void
986 flap_connection_recv_cb(gpointer data, gint source, PurpleInputCondition cond)
987 {
988 FlapConnection *conn = data;
989
990 flap_connection_recv(conn);
991 }
992
993 void
994 flap_connection_recv_cb_ssl(gpointer data, PurpleSslConnection *gsc, PurpleInputCondition cond)
995 {
996 FlapConnection *conn = data;
997
998 flap_connection_recv(conn);
999 }
1000
967 static void 1001 static void
968 send_cb(gpointer data, gint source, PurpleInputCondition cond) 1002 send_cb(gpointer data, gint source, PurpleInputCondition cond)
969 { 1003 {
970 FlapConnection *conn; 1004 FlapConnection *conn;
971 int writelen, ret; 1005 int writelen, ret;
978 purple_input_remove(conn->watcher_outgoing); 1012 purple_input_remove(conn->watcher_outgoing);
979 conn->watcher_outgoing = 0; 1013 conn->watcher_outgoing = 0;
980 return; 1014 return;
981 } 1015 }
982 1016
983 ret = send(conn->fd, conn->buffer_outgoing->outptr, writelen, 0); 1017 if (conn->gsc)
1018 ret = purple_ssl_write(conn->gsc, conn->buffer_outgoing->outptr,
1019 writelen);
1020 else
1021 ret = send(conn->fd, conn->buffer_outgoing->outptr, writelen, 0);
984 if (ret <= 0) 1022 if (ret <= 0)
985 { 1023 {
986 if (ret < 0 && ((errno == EAGAIN) || (errno == EWOULDBLOCK))) 1024 if (ret < 0 && ((errno == EAGAIN) || (errno == EWOULDBLOCK)))
987 /* No worries */ 1025 /* No worries */
988 return; 1026 return;
989 1027
990 /* Error! */ 1028 /* Error! */
991 purple_input_remove(conn->watcher_outgoing); 1029 purple_input_remove(conn->watcher_outgoing);
992 conn->watcher_outgoing = 0; 1030 conn->watcher_outgoing = 0;
993 close(conn->fd); 1031 if (conn->gsc) {
994 conn->fd = -1; 1032 purple_ssl_close(conn->gsc);
1033 conn->gsc = NULL;
1034 } else {
1035 close(conn->fd);
1036 conn->fd = -1;
1037 }
995 flap_connection_schedule_destroy(conn, 1038 flap_connection_schedule_destroy(conn,
996 OSCAR_DISCONNECT_LOST_CONNECTION, g_strerror(errno)); 1039 OSCAR_DISCONNECT_LOST_CONNECTION, g_strerror(errno));
997 return; 1040 return;
998 } 1041 }
999 1042
1015 1058
1016 /* Add everything to our outgoing buffer */ 1059 /* Add everything to our outgoing buffer */
1017 purple_circ_buffer_append(conn->buffer_outgoing, bs->data, count); 1060 purple_circ_buffer_append(conn->buffer_outgoing, bs->data, count);
1018 1061
1019 /* If we haven't already started writing stuff, then start the cycle */ 1062 /* If we haven't already started writing stuff, then start the cycle */
1020 if ((conn->watcher_outgoing == 0) && (conn->fd >= 0)) 1063 if (conn->watcher_outgoing == 0)
1021 { 1064 {
1022 conn->watcher_outgoing = purple_input_add(conn->fd, 1065 if (conn->gsc) {
1023 PURPLE_INPUT_WRITE, send_cb, conn); 1066 conn->watcher_outgoing = purple_input_add(conn->gsc->fd,
1024 send_cb(conn, conn->fd, 0); 1067 PURPLE_INPUT_WRITE, send_cb, conn);
1068 send_cb(conn, 0, 0);
1069 } else if (conn->fd >= 0) {
1070 conn->watcher_outgoing = purple_input_add(conn->fd,
1071 PURPLE_INPUT_WRITE, send_cb, conn);
1072 send_cb(conn, 0, 0);
1073 }
1025 } 1074 }
1026 } 1075 }
1027 1076
1028 static void 1077 static void
1029 sendframe_flap(FlapConnection *conn, FlapFrame *frame) 1078 sendframe_flap(FlapConnection *conn, FlapFrame *frame)