aboutsummaryrefslogtreecommitdiff
path: root/src/util/server.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2015-02-21 20:21:40 +0000
committerChristian Grothoff <christian@grothoff.org>2015-02-21 20:21:40 +0000
commit9e308ff38737cc6b1d840eb72d016a7d1e109ea4 (patch)
tree07f4ed30972e879eca11c36dc4b2619bb153d35a /src/util/server.c
parent0359101b306e170ecca31520ca12081e09d1804f (diff)
downloadgnunet-9e308ff38737cc6b1d840eb72d016a7d1e109ea4.tar.gz
gnunet-9e308ff38737cc6b1d840eb72d016a7d1e109ea4.zip
-signal connection failure to receive even if receive is triggered after failure is observed
Diffstat (limited to 'src/util/server.c')
-rw-r--r--src/util/server.c114
1 files changed, 77 insertions, 37 deletions
diff --git a/src/util/server.c b/src/util/server.c
index d05df089f..279b65792 100644
--- a/src/util/server.c
+++ b/src/util/server.c
@@ -479,10 +479,13 @@ open_listen_socket (const struct sockaddr *server_addr, socklen_t socklen)
479 * fail if we already took the port on IPv6; if both IPv4 and 479 * fail if we already took the port on IPv6; if both IPv4 and
480 * IPv6 binds fail, then our caller will log using the 480 * IPv6 binds fail, then our caller will log using the
481 * errno preserved in 'eno' */ 481 * errno preserved in 'eno' */
482 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "bind"); 482 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR,
483 "bind");
483 if (0 != port) 484 if (0 != port)
484 LOG (GNUNET_ERROR_TYPE_ERROR, _("`%s' failed for port %d (%s).\n"), 485 LOG (GNUNET_ERROR_TYPE_ERROR,
485 "bind", port, 486 _("`%s' failed for port %d (%s).\n"),
487 "bind",
488 port,
486 (AF_INET == server_addr->sa_family) ? "IPv4" : "IPv6"); 489 (AF_INET == server_addr->sa_family) ? "IPv4" : "IPv6");
487 eno = 0; 490 eno = 0;
488 } 491 }
@@ -507,13 +510,15 @@ open_listen_socket (const struct sockaddr *server_addr, socklen_t socklen)
507 } 510 }
508 if (GNUNET_OK != GNUNET_NETWORK_socket_listen (sock, 5)) 511 if (GNUNET_OK != GNUNET_NETWORK_socket_listen (sock, 5))
509 { 512 {
510 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "listen"); 513 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR,
514 "listen");
511 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock)); 515 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock));
512 errno = 0; 516 errno = 0;
513 return NULL; 517 return NULL;
514 } 518 }
515 if (0 != port) 519 if (0 != port)
516 LOG (GNUNET_ERROR_TYPE_DEBUG, "Server starts to listen on port %u.\n", 520 LOG (GNUNET_ERROR_TYPE_DEBUG,
521 "Server starts to listen on port %u.\n",
517 port); 522 port);
518 return sock; 523 return sock;
519} 524}
@@ -620,7 +625,7 @@ GNUNET_SERVER_create (GNUNET_CONNECTION_AccessCheck access_cb,
620 { 625 {
621 lsocks = NULL; 626 lsocks = NULL;
622 } 627 }
623 return GNUNET_SERVER_create_with_sockets (access_cb, 628 return GNUNET_SERVER_create_with_sockets (access_cb,
624 access_cb_cls, 629 access_cb_cls,
625 lsocks, 630 lsocks,
626 idle_timeout, 631 idle_timeout,
@@ -1040,7 +1045,8 @@ process_incoming (void *cls,
1040 * #GNUNET_SYSERR if we should instantly abort due to error in a previous step 1045 * #GNUNET_SYSERR if we should instantly abort due to error in a previous step
1041 */ 1046 */
1042static void 1047static void
1043process_mst (struct GNUNET_SERVER_Client *client, int ret) 1048process_mst (struct GNUNET_SERVER_Client *client,
1049 int ret)
1044{ 1050{
1045 while ((GNUNET_SYSERR != ret) && (NULL != client->server) && 1051 while ((GNUNET_SYSERR != ret) && (NULL != client->server) &&
1046 (GNUNET_YES != client->shutdown_now) && (0 == client->suspended)) 1052 (GNUNET_YES != client->shutdown_now) && (0 == client->suspended))
@@ -1053,7 +1059,8 @@ process_mst (struct GNUNET_SERVER_Client *client, int ret)
1053 client->receive_pending = GNUNET_YES; 1059 client->receive_pending = GNUNET_YES;
1054 GNUNET_CONNECTION_receive (client->connection, 1060 GNUNET_CONNECTION_receive (client->connection,
1055 GNUNET_SERVER_MAX_MESSAGE_SIZE - 1, 1061 GNUNET_SERVER_MAX_MESSAGE_SIZE - 1,
1056 client->idle_timeout, &process_incoming, 1062 client->idle_timeout,
1063 &process_incoming,
1057 client); 1064 client);
1058 break; 1065 break;
1059 } 1066 }
@@ -1092,12 +1099,16 @@ process_mst (struct GNUNET_SERVER_Client *client, int ret)
1092 * @param buf buffer with data received from network 1099 * @param buf buffer with data received from network
1093 * @param available number of bytes available in buf 1100 * @param available number of bytes available in buf
1094 * @param addr address of the sender 1101 * @param addr address of the sender
1095 * @param addrlen length of addr 1102 * @param addrlen length of @a addr
1096 * @param errCode code indicating errors receiving, 0 for success 1103 * @param errCode code indicating errors receiving, 0 for success
1097 */ 1104 */
1098static void 1105static void
1099process_incoming (void *cls, const void *buf, size_t available, 1106process_incoming (void *cls,
1100 const struct sockaddr *addr, socklen_t addrlen, int errCode) 1107 const void *buf,
1108 size_t available,
1109 const struct sockaddr *addr,
1110 socklen_t addrlen,
1111 int errCode)
1101{ 1112{
1102 struct GNUNET_SERVER_Client *client = cls; 1113 struct GNUNET_SERVER_Client *client = cls;
1103 struct GNUNET_SERVER_Handle *server = client->server; 1114 struct GNUNET_SERVER_Handle *server = client->server;
@@ -1108,17 +1119,22 @@ process_incoming (void *cls, const void *buf, size_t available,
1108 GNUNET_assert (GNUNET_YES == client->receive_pending); 1119 GNUNET_assert (GNUNET_YES == client->receive_pending);
1109 client->receive_pending = GNUNET_NO; 1120 client->receive_pending = GNUNET_NO;
1110 now = GNUNET_TIME_absolute_get (); 1121 now = GNUNET_TIME_absolute_get ();
1111 end = GNUNET_TIME_absolute_add (client->last_activity, client->idle_timeout); 1122 end = GNUNET_TIME_absolute_add (client->last_activity,
1112 1123 client->idle_timeout);
1113 if ((NULL == buf) && (0 == available) && (NULL == addr) && (0 == errCode) && 1124
1114 (GNUNET_YES != client->shutdown_now) && (NULL != server) && 1125 if ( (NULL == buf) &&
1115 (GNUNET_YES == GNUNET_CONNECTION_check (client->connection)) && 1126 (0 == available) &&
1116 (end.abs_value_us > now.abs_value_us)) 1127 (NULL == addr) &&
1128 (0 == errCode) &&
1129 (GNUNET_YES != client->shutdown_now) &&
1130 (NULL != server) &&
1131 (GNUNET_YES == GNUNET_CONNECTION_check (client->connection)) &&
1132 (end.abs_value_us > now.abs_value_us) )
1117 { 1133 {
1118 /* wait longer, timeout changed (i.e. due to us sending) */ 1134 /* wait longer, timeout changed (i.e. due to us sending) */
1119 LOG (GNUNET_ERROR_TYPE_DEBUG, 1135 LOG (GNUNET_ERROR_TYPE_DEBUG,
1120 "Receive time out, but no disconnect due to sending (%p)\n", 1136 "Receive time out, but no disconnect due to sending (%p)\n",
1121 GNUNET_a2s (addr, addrlen)); 1137 client);
1122 client->receive_pending = GNUNET_YES; 1138 client->receive_pending = GNUNET_YES;
1123 GNUNET_CONNECTION_receive (client->connection, 1139 GNUNET_CONNECTION_receive (client->connection,
1124 GNUNET_SERVER_MAX_MESSAGE_SIZE - 1, 1140 GNUNET_SERVER_MAX_MESSAGE_SIZE - 1,
@@ -1126,27 +1142,45 @@ process_incoming (void *cls, const void *buf, size_t available,
1126 &process_incoming, client); 1142 &process_incoming, client);
1127 return; 1143 return;
1128 } 1144 }
1129 if ((NULL == buf) || (0 == available) || (0 != errCode) || (NULL == server) || 1145 if ( (NULL == buf) ||
1130 (GNUNET_YES == client->shutdown_now) || 1146 (0 == available) ||
1131 (GNUNET_YES != GNUNET_CONNECTION_check (client->connection))) 1147 (0 != errCode) ||
1148 (NULL == server) ||
1149 (GNUNET_YES == client->shutdown_now) ||
1150 (GNUNET_YES != GNUNET_CONNECTION_check (client->connection)) )
1132 { 1151 {
1133 /* other side closed connection, error connecting, etc. */ 1152 /* other side closed connection, error connecting, etc. */
1153 LOG (GNUNET_ERROR_TYPE_DEBUG,
1154 "Failed to connect or other side closed connection (%p)\n",
1155 client);
1134 GNUNET_SERVER_client_disconnect (client); 1156 GNUNET_SERVER_client_disconnect (client);
1135 return; 1157 return;
1136 } 1158 }
1137 LOG (GNUNET_ERROR_TYPE_DEBUG, "Server receives %u bytes from `%s'.\n", 1159 LOG (GNUNET_ERROR_TYPE_DEBUG,
1138 (unsigned int) available, GNUNET_a2s (addr, addrlen)); 1160 "Server receives %u bytes from `%s'.\n",
1161 (unsigned int) available,
1162 GNUNET_a2s (addr, addrlen));
1139 GNUNET_SERVER_client_keep (client); 1163 GNUNET_SERVER_client_keep (client);
1140 client->last_activity = now; 1164 client->last_activity = now;
1141 1165
1142 if (NULL != server->mst_receive) 1166 if (NULL != server->mst_receive)
1143 ret = 1167 {
1144 client->server->mst_receive (client->server->mst_cls, client->mst, 1168 ret = client->server->mst_receive (client->server->mst_cls,
1145 client, buf, available, GNUNET_NO, GNUNET_YES); 1169 client->mst,
1170 client,
1171 buf,
1172 available,
1173 GNUNET_NO,
1174 GNUNET_YES);
1175 }
1146 else if (NULL != client->mst) 1176 else if (NULL != client->mst)
1147 { 1177 {
1148 ret = 1178 ret =
1149 GNUNET_SERVER_mst_receive (client->mst, client, buf, available, GNUNET_NO, 1179 GNUNET_SERVER_mst_receive (client->mst,
1180 client,
1181 buf,
1182 available,
1183 GNUNET_NO,
1150 GNUNET_YES); 1184 GNUNET_YES);
1151 } 1185 }
1152 else 1186 else
@@ -1154,8 +1188,8 @@ process_incoming (void *cls, const void *buf, size_t available,
1154 GNUNET_break (0); 1188 GNUNET_break (0);
1155 return; 1189 return;
1156 } 1190 }
1157 1191 process_mst (client,
1158 process_mst (client, ret); 1192 ret);
1159 GNUNET_SERVER_client_drop (client); 1193 GNUNET_SERVER_client_drop (client);
1160} 1194}
1161 1195
@@ -1164,11 +1198,12 @@ process_incoming (void *cls, const void *buf, size_t available,
1164 * Task run to start again receiving from the network 1198 * Task run to start again receiving from the network
1165 * and process requests. 1199 * and process requests.
1166 * 1200 *
1167 * @param cls our 'struct GNUNET_SERVER_Client*' to process more requests from 1201 * @param cls our `struct GNUNET_SERVER_Client *` to process more requests from
1168 * @param tc scheduler context (unused) 1202 * @param tc scheduler context (unused)
1169 */ 1203 */
1170static void 1204static void
1171restart_processing (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 1205restart_processing (void *cls,
1206 const struct GNUNET_SCHEDULER_TaskContext *tc)
1172{ 1207{
1173 struct GNUNET_SERVER_Client *client = cls; 1208 struct GNUNET_SERVER_Client *client = cls;
1174 1209
@@ -1180,14 +1215,17 @@ restart_processing (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1180 client->receive_pending = GNUNET_YES; 1215 client->receive_pending = GNUNET_YES;
1181 GNUNET_CONNECTION_receive (client->connection, 1216 GNUNET_CONNECTION_receive (client->connection,
1182 GNUNET_SERVER_MAX_MESSAGE_SIZE - 1, 1217 GNUNET_SERVER_MAX_MESSAGE_SIZE - 1,
1183 client->idle_timeout, &process_incoming, client); 1218 client->idle_timeout,
1219 &process_incoming,
1220 client);
1184 return; 1221 return;
1185 } 1222 }
1186 LOG (GNUNET_ERROR_TYPE_DEBUG, 1223 LOG (GNUNET_ERROR_TYPE_DEBUG,
1187 "Server continues processing messages still in the buffer.\n"); 1224 "Server continues processing messages still in the buffer.\n");
1188 GNUNET_SERVER_client_keep (client); 1225 GNUNET_SERVER_client_keep (client);
1189 client->receive_pending = GNUNET_NO; 1226 client->receive_pending = GNUNET_NO;
1190 process_mst (client, GNUNET_NO); 1227 process_mst (client,
1228 GNUNET_NO);
1191 GNUNET_SERVER_client_drop (client); 1229 GNUNET_SERVER_client_drop (client);
1192} 1230}
1193 1231
@@ -1258,15 +1296,17 @@ GNUNET_SERVER_connect_socket (struct GNUNET_SERVER_Handle *server,
1258 server->mst_create (server->mst_cls, client); 1296 server->mst_create (server->mst_cls, client);
1259 else 1297 else
1260 client->mst = 1298 client->mst =
1261 GNUNET_SERVER_mst_create (&client_message_tokenizer_callback, server); 1299 GNUNET_SERVER_mst_create (&client_message_tokenizer_callback,
1300 server);
1262 GNUNET_assert (NULL != client->mst); 1301 GNUNET_assert (NULL != client->mst);
1263 for (n = server->connect_notify_list_head; NULL != n; n = n->next) 1302 for (n = server->connect_notify_list_head; NULL != n; n = n->next)
1264 n->callback (n->callback_cls, client); 1303 n->callback (n->callback_cls, client);
1265
1266 client->receive_pending = GNUNET_YES; 1304 client->receive_pending = GNUNET_YES;
1267 GNUNET_CONNECTION_receive (client->connection, 1305 GNUNET_CONNECTION_receive (client->connection,
1268 GNUNET_SERVER_MAX_MESSAGE_SIZE - 1, 1306 GNUNET_SERVER_MAX_MESSAGE_SIZE - 1,
1269 client->idle_timeout, &process_incoming, client); 1307 client->idle_timeout,
1308 &process_incoming,
1309 client);
1270 return client; 1310 return client;
1271} 1311}
1272 1312
@@ -1572,7 +1612,7 @@ GNUNET_SERVER_client_disable_corking (struct GNUNET_SERVER_Client *client)
1572 * Wrapper for transmission notification that calls the original 1612 * Wrapper for transmission notification that calls the original
1573 * callback and update the last activity time for our connection. 1613 * callback and update the last activity time for our connection.
1574 * 1614 *
1575 * @param cls the `struct GNUNET_SERVER_Client` 1615 * @param cls the `struct GNUNET_SERVER_Client *`
1576 * @param size number of bytes we can transmit 1616 * @param size number of bytes we can transmit
1577 * @param buf where to copy the message 1617 * @param buf where to copy the message
1578 * @return number of bytes actually transmitted 1618 * @return number of bytes actually transmitted