aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp/sm_sideeffect.c
diff options
context:
space:
mode:
authorFrank Filz <ffilzlnx@us.ibm.com>2005-06-20 16:14:57 -0400
committerDavid S. Miller <davem@davemloft.net>2005-06-20 16:14:57 -0400
commit3f7a87d2fa9b42f7aade43914f060df68cc89cc7 (patch)
tree15162d2dd770428f98a0d39f8dc6063aba0ad1e6 /net/sctp/sm_sideeffect.c
parent8b22c249e7de453961e4d253b19fc2a0bdd65d53 (diff)
[SCTP] sctp_connectx() API support
Implements sctp_connectx() as defined in the SCTP sockets API draft by tunneling the request through a setsockopt(). Signed-off-by: Frank Filz <ffilzlnx@us.ibm.com> Signed-off-by: Sridhar Samudrala <sri@us.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sctp/sm_sideeffect.c')
-rw-r--r--net/sctp/sm_sideeffect.c105
1 files changed, 85 insertions, 20 deletions
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
index f65fa441952f..778639db125a 100644
--- a/net/sctp/sm_sideeffect.c
+++ b/net/sctp/sm_sideeffect.c
@@ -414,11 +414,13 @@ static void sctp_do_8_2_transport_strike(struct sctp_association *asoc,
414 */ 414 */
415 asoc->overall_error_count++; 415 asoc->overall_error_count++;
416 416
417 if (transport->active && 417 if (transport->state != SCTP_INACTIVE &&
418 (transport->error_count++ >= transport->max_retrans)) { 418 (transport->error_count++ >= transport->max_retrans)) {
419 SCTP_DEBUG_PRINTK("transport_strike: transport " 419 SCTP_DEBUG_PRINTK_IPADDR("transport_strike:association %p",
420 "IP:%d.%d.%d.%d failed.\n", 420 " transport IP: port:%d failed.\n",
421 NIPQUAD(transport->ipaddr.v4.sin_addr)); 421 asoc,
422 (&transport->ipaddr),
423 transport->ipaddr.v4.sin_port);
422 sctp_assoc_control_transport(asoc, transport, 424 sctp_assoc_control_transport(asoc, transport,
423 SCTP_TRANSPORT_DOWN, 425 SCTP_TRANSPORT_DOWN,
424 SCTP_FAILED_THRESHOLD); 426 SCTP_FAILED_THRESHOLD);
@@ -593,7 +595,7 @@ static void sctp_cmd_transport_on(sctp_cmd_seq_t *cmds,
593 /* Mark the destination transport address as active if it is not so 595 /* Mark the destination transport address as active if it is not so
594 * marked. 596 * marked.
595 */ 597 */
596 if (!t->active) 598 if (t->state == SCTP_INACTIVE)
597 sctp_assoc_control_transport(asoc, t, SCTP_TRANSPORT_UP, 599 sctp_assoc_control_transport(asoc, t, SCTP_TRANSPORT_UP,
598 SCTP_HEARTBEAT_SUCCESS); 600 SCTP_HEARTBEAT_SUCCESS);
599 601
@@ -665,8 +667,11 @@ static void sctp_cmd_new_state(sctp_cmd_seq_t *cmds,
665 667
666 asoc->state = state; 668 asoc->state = state;
667 669
670 SCTP_DEBUG_PRINTK("sctp_cmd_new_state: asoc %p[%s]\n",
671 asoc, sctp_state_tbl[state]);
672
668 if (sctp_style(sk, TCP)) { 673 if (sctp_style(sk, TCP)) {
669 /* Change the sk->sk_state of a TCP-style socket that has 674 /* Change the sk->sk_state of a TCP-style socket that has
670 * sucessfully completed a connect() call. 675 * sucessfully completed a connect() call.
671 */ 676 */
672 if (sctp_state(asoc, ESTABLISHED) && sctp_sstate(sk, CLOSED)) 677 if (sctp_state(asoc, ESTABLISHED) && sctp_sstate(sk, CLOSED))
@@ -678,6 +683,16 @@ static void sctp_cmd_new_state(sctp_cmd_seq_t *cmds,
678 sk->sk_shutdown |= RCV_SHUTDOWN; 683 sk->sk_shutdown |= RCV_SHUTDOWN;
679 } 684 }
680 685
686 if (sctp_state(asoc, COOKIE_WAIT)) {
687 /* Reset init timeouts since they may have been
688 * increased due to timer expirations.
689 */
690 asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_INIT] =
691 asoc->ep->timeouts[SCTP_EVENT_TIMEOUT_T1_INIT];
692 asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_COOKIE] =
693 asoc->ep->timeouts[SCTP_EVENT_TIMEOUT_T1_COOKIE];
694 }
695
681 if (sctp_state(asoc, ESTABLISHED) || 696 if (sctp_state(asoc, ESTABLISHED) ||
682 sctp_state(asoc, CLOSED) || 697 sctp_state(asoc, CLOSED) ||
683 sctp_state(asoc, SHUTDOWN_RECEIVED)) { 698 sctp_state(asoc, SHUTDOWN_RECEIVED)) {
@@ -1120,10 +1135,10 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
1120 * to be executed only during failed attempts of 1135 * to be executed only during failed attempts of
1121 * association establishment. 1136 * association establishment.
1122 */ 1137 */
1123 if ((asoc->peer.retran_path != 1138 if ((asoc->peer.retran_path !=
1124 asoc->peer.primary_path) && 1139 asoc->peer.primary_path) &&
1125 (asoc->counters[SCTP_COUNTER_INIT_ERROR] > 0)) { 1140 (asoc->init_err_counter > 0)) {
1126 sctp_add_cmd_sf(commands, 1141 sctp_add_cmd_sf(commands,
1127 SCTP_CMD_FORCE_PRIM_RETRAN, 1142 SCTP_CMD_FORCE_PRIM_RETRAN,
1128 SCTP_NULL()); 1143 SCTP_NULL());
1129 } 1144 }
@@ -1237,18 +1252,67 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
1237 sctp_association_put(asoc); 1252 sctp_association_put(asoc);
1238 break; 1253 break;
1239 1254
1255 case SCTP_CMD_INIT_CHOOSE_TRANSPORT:
1256 chunk = cmd->obj.ptr;
1257 t = sctp_assoc_choose_init_transport(asoc);
1258 asoc->init_last_sent_to = t;
1259 chunk->transport = t;
1260 t->init_sent_count++;
1261 break;
1262
1240 case SCTP_CMD_INIT_RESTART: 1263 case SCTP_CMD_INIT_RESTART:
1241 /* Do the needed accounting and updates 1264 /* Do the needed accounting and updates
1242 * associated with restarting an initialization 1265 * associated with restarting an initialization
1243 * timer. 1266 * timer. Only multiply the timeout by two if
1267 * all transports have been tried at the current
1268 * timeout.
1269 */
1270 t = asoc->init_last_sent_to;
1271 asoc->init_err_counter++;
1272
1273 if (t->init_sent_count > (asoc->init_cycle + 1)) {
1274 asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_INIT] *= 2;
1275 if (asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_INIT] >
1276 asoc->max_init_timeo) {
1277 asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_INIT] =
1278 asoc->max_init_timeo;
1279 }
1280 asoc->init_cycle++;
1281 SCTP_DEBUG_PRINTK(
1282 "T1 INIT Timeout adjustment"
1283 " init_err_counter: %d"
1284 " cycle: %d"
1285 " timeout: %d\n",
1286 asoc->init_err_counter,
1287 asoc->init_cycle,
1288 asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_INIT]);
1289 }
1290
1291 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,
1292 SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT));
1293 break;
1294
1295 case SCTP_CMD_COOKIEECHO_RESTART:
1296 /* Do the needed accounting and updates
1297 * associated with restarting an initialization
1298 * timer. Only multiply the timeout by two if
1299 * all transports have been tried at the current
1300 * timeout.
1244 */ 1301 */
1245 asoc->counters[SCTP_COUNTER_INIT_ERROR]++; 1302 asoc->init_err_counter++;
1246 asoc->timeouts[cmd->obj.to] *= 2; 1303
1247 if (asoc->timeouts[cmd->obj.to] > 1304 asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_COOKIE] *= 2;
1305 if (asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_COOKIE] >
1248 asoc->max_init_timeo) { 1306 asoc->max_init_timeo) {
1249 asoc->timeouts[cmd->obj.to] = 1307 asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_COOKIE] =
1250 asoc->max_init_timeo; 1308 asoc->max_init_timeo;
1251 } 1309 }
1310 SCTP_DEBUG_PRINTK(
1311 "T1 COOKIE Timeout adjustment"
1312 " init_err_counter: %d"
1313 " timeout: %d\n",
1314 asoc->init_err_counter,
1315 asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_COOKIE]);
1252 1316
1253 /* If we've sent any data bundled with 1317 /* If we've sent any data bundled with
1254 * COOKIE-ECHO we need to resend. 1318 * COOKIE-ECHO we need to resend.
@@ -1261,7 +1325,7 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
1261 1325
1262 sctp_add_cmd_sf(commands, 1326 sctp_add_cmd_sf(commands,
1263 SCTP_CMD_TIMER_RESTART, 1327 SCTP_CMD_TIMER_RESTART,
1264 SCTP_TO(cmd->obj.to)); 1328 SCTP_TO(SCTP_EVENT_TIMEOUT_T1_COOKIE));
1265 break; 1329 break;
1266 1330
1267 case SCTP_CMD_INIT_FAILED: 1331 case SCTP_CMD_INIT_FAILED:
@@ -1273,12 +1337,13 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
1273 subtype, chunk, cmd->obj.u32); 1337 subtype, chunk, cmd->obj.u32);
1274 break; 1338 break;
1275 1339
1276 case SCTP_CMD_COUNTER_INC: 1340 case SCTP_CMD_INIT_COUNTER_INC:
1277 asoc->counters[cmd->obj.counter]++; 1341 asoc->init_err_counter++;
1278 break; 1342 break;
1279 1343
1280 case SCTP_CMD_COUNTER_RESET: 1344 case SCTP_CMD_INIT_COUNTER_RESET:
1281 asoc->counters[cmd->obj.counter] = 0; 1345 asoc->init_err_counter = 0;
1346 asoc->init_cycle = 0;
1282 break; 1347 break;
1283 1348
1284 case SCTP_CMD_REPORT_DUP: 1349 case SCTP_CMD_REPORT_DUP: