Linux HLSW LAN Master
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

86 lines
1.8 KiB

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <time.h>
  5. #include "gamelist.h"
  6. #include "logging.h"
  7. #define BUCKET_NUM 127
  8. static struct list_head *bucket;
  9. static unsigned int hash_entry(struct game_entry *entry)
  10. {
  11. unsigned int hash = 0x12345678;
  12. hash = ((hash << 5) ^ (hash >> 27)) ^ ((entry->ip >> 0) & 0xFF);
  13. hash = ((hash << 5) ^ (hash >> 27)) ^ ((entry->ip >> 8) & 0xFF);
  14. hash = ((hash << 5) ^ (hash >> 27)) ^ ((entry->ip >> 16) & 0xFF);
  15. hash = ((hash << 5) ^ (hash >> 27)) ^ ((entry->ip >> 24) & 0xFF);
  16. hash = ((hash << 5) ^ (hash >> 27)) ^ ((entry->port1 >> 0) & 0xFF);
  17. hash = ((hash << 5) ^ (hash >> 27)) ^ ((entry->port1 >> 8) & 0xFF);
  18. return hash % BUCKET_NUM;
  19. }
  20. static int compare_entry(struct game_entry *a, struct game_entry *b)
  21. {
  22. return (a->gameid == b->gameid && a->ip == b->ip &&
  23. a->port1 == b->port1 && a->port2 == b->port2);
  24. }
  25. int gamelist_add(struct game_entry *entry)
  26. {
  27. unsigned int hash = hash_entry(entry);
  28. struct game_entry *search;
  29. list_for_each_entry(search, &bucket[hash], list) {
  30. if (compare_entry(search, entry)) {
  31. search->modtime = time(NULL);
  32. return 0;
  33. }
  34. }
  35. entry->modtime = time(NULL);
  36. list_add_tail(&entry->list, &bucket[hash]);
  37. return 0;
  38. }
  39. int gamelist_gc_and_dump(int (*callback)(struct game_entry *entry), int timeout)
  40. {
  41. long now = time(NULL);
  42. int i;
  43. for (i = 0; i < BUCKET_NUM; i++) {
  44. struct game_entry *entry, *tmp;
  45. list_for_each_entry_safe(entry, tmp, &bucket[i], list) {
  46. if (entry->modtime + timeout >= now) {
  47. callback(entry);
  48. } else {
  49. list_del(&entry->list);
  50. free(entry);
  51. }
  52. }
  53. }
  54. return 0;
  55. }
  56. int gamelist_init()
  57. {
  58. bucket = malloc(sizeof(struct list_head) * BUCKET_NUM);
  59. if (bucket == NULL) {
  60. log_print(LOG_ERROR, "scan_init(): out of memory");
  61. return -1;
  62. }
  63. int i;
  64. for (i = 0; i < BUCKET_NUM; i++)
  65. INIT_LIST_HEAD(&bucket[i]);
  66. return 0;
  67. }