comparison src/event/ngx_event_openssl.c @ 1027:ff07ccfaad50

fix duplicate rbtree keys case
author Igor Sysoev <igor@sysoev.ru>
date Fri, 12 Jan 2007 20:57:34 +0000
parents f88651afad40
children ce08bc4cb97b
comparison
equal deleted inserted replaced
1026:38be15c1379a 1027:ff07ccfaad50
30 static ngx_ssl_session_t *ngx_ssl_get_cached_session(ngx_ssl_conn_t *ssl_conn, 30 static ngx_ssl_session_t *ngx_ssl_get_cached_session(ngx_ssl_conn_t *ssl_conn,
31 u_char *id, int len, int *copy); 31 u_char *id, int len, int *copy);
32 static void ngx_ssl_remove_session(SSL_CTX *ssl, ngx_ssl_session_t *sess); 32 static void ngx_ssl_remove_session(SSL_CTX *ssl, ngx_ssl_session_t *sess);
33 static void ngx_ssl_expire_sessions(ngx_ssl_session_cache_t *cache, 33 static void ngx_ssl_expire_sessions(ngx_ssl_session_cache_t *cache,
34 ngx_slab_pool_t *shpool, ngx_uint_t n); 34 ngx_slab_pool_t *shpool, ngx_uint_t n);
35 static void ngx_ssl_session_rbtree_insert_value(ngx_rbtree_node_t *temp,
36 ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel);
35 37
36 static void *ngx_openssl_create_conf(ngx_cycle_t *cycle); 38 static void *ngx_openssl_create_conf(ngx_cycle_t *cycle);
37 static char *ngx_openssl_init_conf(ngx_cycle_t *cycle, void *conf); 39 static char *ngx_openssl_init_conf(ngx_cycle_t *cycle, void *conf);
38 static void ngx_openssl_exit(ngx_cycle_t *cycle); 40 static void ngx_openssl_exit(ngx_cycle_t *cycle);
39 41
1221 1223
1222 ngx_rbtree_sentinel_init(sentinel); 1224 ngx_rbtree_sentinel_init(sentinel);
1223 1225
1224 cache->session_rbtree->root = sentinel; 1226 cache->session_rbtree->root = sentinel;
1225 cache->session_rbtree->sentinel = sentinel; 1227 cache->session_rbtree->sentinel = sentinel;
1226 cache->session_rbtree->insert = ngx_rbtree_insert_value; 1228 cache->session_rbtree->insert = ngx_ssl_session_rbtree_insert_value;
1227 1229
1228 shm_zone->data = cache; 1230 shm_zone->data = cache;
1229 1231
1230 return NGX_OK; 1232 return NGX_OK;
1231 } 1233 }
1378 #if OPENSSL_VERSION_NUMBER >= 0x0090707fL 1380 #if OPENSSL_VERSION_NUMBER >= 0x0090707fL
1379 const 1381 const
1380 #endif 1382 #endif
1381 u_char *p; 1383 u_char *p;
1382 uint32_t hash; 1384 uint32_t hash;
1385 ngx_int_t rc;
1383 ngx_time_t *tp; 1386 ngx_time_t *tp;
1384 ngx_shm_zone_t *shm_zone; 1387 ngx_shm_zone_t *shm_zone;
1385 ngx_slab_pool_t *shpool; 1388 ngx_slab_pool_t *shpool;
1386 ngx_connection_t *c; 1389 ngx_connection_t *c;
1387 ngx_rbtree_node_t *node, *sentinel; 1390 ngx_rbtree_node_t *node, *sentinel;
1390 ngx_ssl_session_cache_t *cache; 1393 ngx_ssl_session_cache_t *cache;
1391 u_char buf[NGX_SSL_MAX_SESSION_SIZE]; 1394 u_char buf[NGX_SSL_MAX_SESSION_SIZE];
1392 1395
1393 c = ngx_ssl_get_connection(ssl_conn); 1396 c = ngx_ssl_get_connection(ssl_conn);
1394 1397
1395 hash = ngx_crc32_short(id, len); 1398 hash = ngx_crc32_short(id, (size_t) len);
1396 *copy = 0; 1399 *copy = 0;
1397 1400
1398 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, 1401 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
1399 "http ssl get session: %08XD:%d", hash, len); 1402 "http ssl get session: %08XD:%d", hash, len);
1400 1403
1429 } 1432 }
1430 1433
1431 /* hash == node->key */ 1434 /* hash == node->key */
1432 1435
1433 do { 1436 do {
1434 if ((u_char) len == node->data) { 1437 sess_id = (ngx_ssl_sess_id_t *) node;
1435 sess_id = (ngx_ssl_sess_id_t *) node; 1438
1436 1439 rc = ngx_strn2cmp(id, sess_id->id,
1437 if (ngx_strncmp(id, sess_id->id, len) == 0) { 1440 (size_t) len, (size_t) node->data);
1438 1441 if (rc == 0) {
1439 tp = ngx_timeofday(); 1442
1440 1443 tp = ngx_timeofday();
1441 if (sess_id->expire > tp->sec) { 1444
1442 ngx_memcpy(buf, sess_id->session, sess_id->len); 1445 if (sess_id->expire > tp->sec) {
1443 1446 ngx_memcpy(buf, sess_id->session, sess_id->len);
1444 ngx_shmtx_unlock(&shpool->mutex); 1447
1445 1448 ngx_shmtx_unlock(&shpool->mutex);
1446 p = buf; 1449
1447 sess = d2i_SSL_SESSION(NULL, &p, sess_id->len); 1450 p = buf;
1448 1451 sess = d2i_SSL_SESSION(NULL, &p, sess_id->len);
1449 return sess; 1452
1450 } 1453 return sess;
1451 1454 }
1452 sess_id->next->prev = sess_id->prev; 1455
1453 sess_id->prev->next = sess_id->next; 1456 sess_id->next->prev = sess_id->prev;
1454 1457 sess_id->prev->next = sess_id->next;
1455 ngx_rbtree_delete(cache->session_rbtree, node); 1458
1456 1459 ngx_rbtree_delete(cache->session_rbtree, node);
1457 ngx_slab_free_locked(shpool, sess_id->session); 1460
1461 ngx_slab_free_locked(shpool, sess_id->session);
1458 #if (NGX_PTR_SIZE == 4) 1462 #if (NGX_PTR_SIZE == 4)
1459 ngx_slab_free_locked(shpool, sess_id->id); 1463 ngx_slab_free_locked(shpool, sess_id->id);
1460 #endif 1464 #endif
1461 ngx_slab_free_locked(shpool, sess_id); 1465 ngx_slab_free_locked(shpool, sess_id);
1462 1466
1463 sess = NULL; 1467 sess = NULL;
1464 1468
1465 goto done; 1469 goto done;
1466 } 1470 }
1467 } 1471
1468 1472 node = (rc < 0) ? node->left : node->right;
1469 node = node->right;
1470 1473
1471 } while (node != sentinel && hash == node->key); 1474 } while (node != sentinel && hash == node->key);
1472 1475
1473 break; 1476 break;
1474 } 1477 }
1482 1485
1483 1486
1484 static void 1487 static void
1485 ngx_ssl_remove_session(SSL_CTX *ssl, ngx_ssl_session_t *sess) 1488 ngx_ssl_remove_session(SSL_CTX *ssl, ngx_ssl_session_t *sess)
1486 { 1489 {
1487 u_char *id, len; 1490 size_t len;
1491 u_char *id;
1488 uint32_t hash; 1492 uint32_t hash;
1493 ngx_int_t rc;
1489 ngx_shm_zone_t *shm_zone; 1494 ngx_shm_zone_t *shm_zone;
1490 ngx_slab_pool_t *shpool; 1495 ngx_slab_pool_t *shpool;
1491 ngx_rbtree_node_t *node, *sentinel; 1496 ngx_rbtree_node_t *node, *sentinel;
1492 ngx_ssl_sess_id_t *sess_id; 1497 ngx_ssl_sess_id_t *sess_id;
1493 ngx_ssl_session_cache_t *cache; 1498 ngx_ssl_session_cache_t *cache;
1495 shm_zone = SSL_CTX_get_ex_data(ssl, ngx_ssl_session_cache_index); 1500 shm_zone = SSL_CTX_get_ex_data(ssl, ngx_ssl_session_cache_index);
1496 1501
1497 cache = shm_zone->data; 1502 cache = shm_zone->data;
1498 1503
1499 id = sess->session_id; 1504 id = sess->session_id;
1500 len = (u_char) sess->session_id_length; 1505 len = (size_t) sess->session_id_length;
1501 1506
1502 hash = ngx_crc32_short(id, (size_t) len); 1507 hash = ngx_crc32_short(id, len);
1503 1508
1504 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ngx_cycle->log, 0, 1509 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ngx_cycle->log, 0,
1505 "http ssl remove session: %08XD:%d", hash, len); 1510 "http ssl remove session: %08XD:%uz", hash, len);
1506 1511
1507 shpool = (ngx_slab_pool_t *) shm_zone->shm.addr; 1512 shpool = (ngx_slab_pool_t *) shm_zone->shm.addr;
1508 1513
1509 ngx_shmtx_lock(&shpool->mutex); 1514 ngx_shmtx_lock(&shpool->mutex);
1510 1515
1524 } 1529 }
1525 1530
1526 /* hash == node->key */ 1531 /* hash == node->key */
1527 1532
1528 do { 1533 do {
1529 if ((u_char) len == node->data) { 1534 sess_id = (ngx_ssl_sess_id_t *) node;
1530 sess_id = (ngx_ssl_sess_id_t *) node; 1535
1531 1536 rc = ngx_strn2cmp(id, sess_id->id, len, (size_t) node->data);
1532 if (ngx_strncmp(id, sess_id->id, (size_t) len) == 0) { 1537
1533 1538 if (rc == 0) {
1534 sess_id->next->prev = sess_id->prev; 1539 sess_id->next->prev = sess_id->prev;
1535 sess_id->prev->next = sess_id->next; 1540 sess_id->prev->next = sess_id->next;
1536 1541
1537 ngx_rbtree_delete(cache->session_rbtree, node); 1542 ngx_rbtree_delete(cache->session_rbtree, node);
1538 1543
1539 ngx_slab_free_locked(shpool, sess_id->session); 1544 ngx_slab_free_locked(shpool, sess_id->session);
1540 #if (NGX_PTR_SIZE == 4) 1545 #if (NGX_PTR_SIZE == 4)
1541 ngx_slab_free_locked(shpool, sess_id->id); 1546 ngx_slab_free_locked(shpool, sess_id->id);
1542 #endif 1547 #endif
1543 ngx_slab_free_locked(shpool, sess_id); 1548 ngx_slab_free_locked(shpool, sess_id);
1544 1549
1545 goto done; 1550 goto done;
1546 } 1551 }
1547 } 1552
1548 1553 node = (rc < 0) ? node->left : node->right;
1549 node = node->right;
1550 1554
1551 } while (node != sentinel && hash == node->key); 1555 } while (node != sentinel && hash == node->key);
1552 1556
1553 break; 1557 break;
1554 } 1558 }
1593 ngx_slab_free_locked(shpool, sess_id->id); 1597 ngx_slab_free_locked(shpool, sess_id->id);
1594 #endif 1598 #endif
1595 ngx_slab_free_locked(shpool, sess_id); 1599 ngx_slab_free_locked(shpool, sess_id);
1596 } 1600 }
1597 } 1601 }
1602
1603
1604 static void
1605 ngx_ssl_session_rbtree_insert_value(ngx_rbtree_node_t *temp,
1606 ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel)
1607 {
1608 ngx_ssl_sess_id_t *sess_id, *sess_id_temp;
1609
1610 for ( ;; ) {
1611
1612 if (node->key < temp->key) {
1613
1614 if (temp->left == sentinel) {
1615 temp->left = node;
1616 break;
1617 }
1618
1619 temp = temp->left;
1620
1621 } else if (node->key > temp->key) {
1622
1623 if (temp->right == sentinel) {
1624 temp->right = node;
1625 break;
1626 }
1627
1628 temp = temp->right;
1629
1630 } else { /* node->key == temp->key */
1631
1632 sess_id = (ngx_ssl_sess_id_t *) node;
1633 sess_id_temp = (ngx_ssl_sess_id_t *) temp;
1634
1635 if (ngx_strn2cmp(sess_id->id, sess_id_temp->id,
1636 (size_t) node->data, (size_t) temp->data)
1637 < 0)
1638 {
1639 if (temp->left == sentinel) {
1640 temp->left = node;
1641 break;
1642 }
1643
1644 temp = temp->left;
1645
1646 } else {
1647
1648 if (temp->right == sentinel) {
1649 temp->right = node;
1650 break;
1651 }
1652
1653 temp = temp->right;
1654 }
1655 }
1656 }
1657
1658 node->parent = temp;
1659 node->left = sentinel;
1660 node->right = sentinel;
1661 ngx_rbt_red(node);
1662 }
1598 1663
1599 1664
1600 void 1665 void
1601 ngx_ssl_cleanup_ctx(void *data) 1666 ngx_ssl_cleanup_ctx(void *data)
1602 { 1667 {