diff options
author | Christian Grothoff <christian@grothoff.org> | 2015-02-21 20:21:40 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2015-02-21 20:21:40 +0000 |
commit | 9e308ff38737cc6b1d840eb72d016a7d1e109ea4 (patch) | |
tree | 07f4ed30972e879eca11c36dc4b2619bb153d35a /src/util/server.c | |
parent | 0359101b306e170ecca31520ca12081e09d1804f (diff) | |
download | gnunet-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.c | 114 |
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 | */ |
1042 | static void | 1047 | static void |
1043 | process_mst (struct GNUNET_SERVER_Client *client, int ret) | 1048 | process_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 | */ |
1098 | static void | 1105 | static void |
1099 | process_incoming (void *cls, const void *buf, size_t available, | 1106 | process_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 | */ |
1170 | static void | 1204 | static void |
1171 | restart_processing (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 1205 | restart_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 |