listener.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. /*
  2. * Dropbear SSH
  3. *
  4. * Copyright (c) 2002,2003 Matt Johnston
  5. * All rights reserved.
  6. *
  7. * Permission is hereby granted, free of charge, to any person obtaining a copy
  8. * of this software and associated documentation files (the "Software"), to deal
  9. * in the Software without restriction, including without limitation the rights
  10. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11. * copies of the Software, and to permit persons to whom the Software is
  12. * furnished to do so, subject to the following conditions:
  13. *
  14. * The above copyright notice and this permission notice shall be included in
  15. * all copies or substantial portions of the Software.
  16. *
  17. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  20. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  22. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  23. * SOFTWARE. */
  24. #include "includes.h"
  25. #include "listener.h"
  26. #include "session.h"
  27. #include "dbutil.h"
  28. void listeners_initialise() {
  29. /* just one slot to start with */
  30. ses.listeners = (struct Listener**)m_malloc(sizeof(struct Listener*));
  31. ses.listensize = 1;
  32. ses.listeners[0] = NULL;
  33. }
  34. void set_listener_fds(fd_set * readfds) {
  35. unsigned int i, j;
  36. struct Listener *listener;
  37. /* check each in turn */
  38. for (i = 0; i < ses.listensize; i++) {
  39. listener = ses.listeners[i];
  40. if (listener != NULL) {
  41. for (j = 0; j < listener->nsocks; j++) {
  42. FD_SET(listener->socks[j], readfds);
  43. }
  44. }
  45. }
  46. }
  47. void handle_listeners(fd_set * readfds) {
  48. unsigned int i, j;
  49. struct Listener *listener;
  50. int sock;
  51. /* check each in turn */
  52. for (i = 0; i < ses.listensize; i++) {
  53. listener = ses.listeners[i];
  54. if (listener != NULL) {
  55. for (j = 0; j < listener->nsocks; j++) {
  56. sock = listener->socks[j];
  57. if (FD_ISSET(sock, readfds)) {
  58. listener->acceptor(listener, sock);
  59. }
  60. }
  61. }
  62. }
  63. } /* Woo brace matching */
  64. /* acceptor(int fd, void* typedata) is a function to accept connections,
  65. * cleanup(void* typedata) happens when cleaning up */
  66. struct Listener* new_listener(int socks[], unsigned int nsocks,
  67. int type, void* typedata,
  68. void (*acceptor)(struct Listener* listener, int sock),
  69. void (*cleanup)(struct Listener*)) {
  70. unsigned int i, j;
  71. struct Listener *newlisten = NULL;
  72. /* try get a new structure to hold it */
  73. for (i = 0; i < ses.listensize; i++) {
  74. if (ses.listeners[i] == NULL) {
  75. break;
  76. }
  77. }
  78. /* or create a new one */
  79. if (i == ses.listensize) {
  80. if (ses.listensize > MAX_LISTENERS) {
  81. TRACE(("leave newlistener: too many already"))
  82. for (j = 0; j < nsocks; j++) {
  83. close(socks[i]);
  84. }
  85. return NULL;
  86. }
  87. ses.listeners = (struct Listener**)m_realloc(ses.listeners,
  88. (ses.listensize+LISTENER_EXTEND_SIZE)
  89. *sizeof(struct Listener*));
  90. ses.listensize += LISTENER_EXTEND_SIZE;
  91. for (j = i; j < ses.listensize; j++) {
  92. ses.listeners[j] = NULL;
  93. }
  94. }
  95. for (j = 0; j < nsocks; j++) {
  96. ses.maxfd = MAX(ses.maxfd, socks[j]);
  97. }
  98. TRACE(("new listener num %d ", i))
  99. newlisten = (struct Listener*)m_malloc(sizeof(struct Listener));
  100. newlisten->index = i;
  101. newlisten->type = type;
  102. newlisten->typedata = typedata;
  103. newlisten->nsocks = nsocks;
  104. memcpy(newlisten->socks, socks, nsocks * sizeof(int));
  105. newlisten->acceptor = acceptor;
  106. newlisten->cleanup = cleanup;
  107. ses.listeners[i] = newlisten;
  108. return newlisten;
  109. }
  110. /* Return the first listener which matches the type-specific comparison
  111. * function. Particularly needed for global requests, like tcp */
  112. struct Listener * get_listener(int type, void* typedata,
  113. int (*match)(void*, void*)) {
  114. unsigned int i;
  115. struct Listener* listener;
  116. for (i = 0, listener = ses.listeners[i]; i < ses.listensize; i++) {
  117. if (listener->type == type
  118. && match(typedata, listener->typedata)) {
  119. return listener;
  120. }
  121. }
  122. return NULL;
  123. }
  124. void remove_listener(struct Listener* listener) {
  125. unsigned int j;
  126. if (listener->cleanup) {
  127. listener->cleanup(listener);
  128. }
  129. for (j = 0; j < listener->nsocks; j++) {
  130. close(listener->socks[j]);
  131. }
  132. ses.listeners[listener->index] = NULL;
  133. m_free(listener);
  134. }
  135. void remove_all_listeners(void) {
  136. unsigned int i;
  137. for (i = 0; i < ses.listensize; i++) {
  138. if (ses.listeners[i]) {
  139. remove_listener(ses.listeners[i]);
  140. }
  141. }
  142. m_free(ses.listeners);
  143. }