aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMatthias Wachs <wachs@net.in.tum.de>2012-02-23 17:35:38 +0000
committerMatthias Wachs <wachs@net.in.tum.de>2012-02-23 17:35:38 +0000
commita881ec667a8e9b40398dcc62cdfb97183e5c77ee (patch)
treed2f9a30c6e9a99f653ee1b6d800261ab51076709 /src
parent0c3dc8571333312dcfe3bf18e383ca85a1fc79b0 (diff)
downloadgnunet-a881ec667a8e9b40398dcc62cdfb97183e5c77ee.tar.gz
gnunet-a881ec667a8e9b40398dcc62cdfb97183e5c77ee.zip
splitted ipv4 and ipv6 socket select scheduling
removed looping for write select improved ipv4/v6 en/disabling session management
Diffstat (limited to 'src')
-rw-r--r--src/transport/plugin_transport_udp.c240
-rw-r--r--src/transport/plugin_transport_udp.h21
2 files changed, 236 insertions, 25 deletions
diff --git a/src/transport/plugin_transport_udp.c b/src/transport/plugin_transport_udp.c
index ccd9d07ee..51c3aa3f3 100644
--- a/src/transport/plugin_transport_udp.c
+++ b/src/transport/plugin_transport_udp.c
@@ -289,7 +289,27 @@ struct UDP_ACK_Message
289 289
290}; 290};
291 291
292/**
293 * We have been notified that our readset has something to read. We don't
294 * know which socket needs to be read, so we have to check each one
295 * Then reschedule this function to be called again once more is available.
296 *
297 * @param cls the plugin handle
298 * @param tc the scheduling context (for rescheduling this function again)
299 */
300static void
301udp_plugin_select (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
292 302
303/**
304 * We have been notified that our readset has something to read. We don't
305 * know which socket needs to be read, so we have to check each one
306 * Then reschedule this function to be called again once more is available.
307 *
308 * @param cls the plugin handle
309 * @param tc the scheduling context (for rescheduling this function again)
310 */
311static void
312udp_plugin_select_v6 (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
293 313
294/** 314/**
295 * Function called for a quick conversion of the binary address to 315 * Function called for a quick conversion of the binary address to
@@ -746,6 +766,7 @@ udp_plugin_get_session (void *cls,
746 GNUNET_assert (plugin != NULL); 766 GNUNET_assert (plugin != NULL);
747 GNUNET_assert (address != NULL); 767 GNUNET_assert (address != NULL);
748 768
769
749 if ((address->address == NULL) || 770 if ((address->address == NULL) ||
750 ((address->address_length != sizeof (struct IPv4UdpAddress)) && 771 ((address->address_length != sizeof (struct IPv4UdpAddress)) &&
751 (address->address_length != sizeof (struct IPv6UdpAddress)))) 772 (address->address_length != sizeof (struct IPv6UdpAddress))))
@@ -754,6 +775,15 @@ udp_plugin_get_session (void *cls,
754 return NULL; 775 return NULL;
755 } 776 }
756 777
778 if ((address->address_length == sizeof (struct IPv4UdpAddress)) &&
779 (plugin->sockv4 == NULL))
780 return NULL;
781
782 if ((address->address_length == sizeof (struct IPv6UdpAddress)) &&
783 (plugin->sockv6 == NULL))
784 return NULL;
785
786
757 /* check if session already exists */ 787 /* check if session already exists */
758 struct SessionCompareContext cctx; 788 struct SessionCompareContext cctx;
759 cctx.addr = address; 789 cctx.addr = address;
@@ -816,6 +846,7 @@ enqueue_fragment (void *cls, const struct GNUNET_MessageHeader *msg)
816 struct FragmentationContext *frag_ctx = cls; 846 struct FragmentationContext *frag_ctx = cls;
817 struct Plugin *plugin = frag_ctx->plugin; 847 struct Plugin *plugin = frag_ctx->plugin;
818 struct UDPMessageWrapper * udpw; 848 struct UDPMessageWrapper * udpw;
849 struct Session *s;
819 850
820 size_t msg_len = ntohs (msg->size); 851 size_t msg_len = ntohs (msg->size);
821 852
@@ -825,6 +856,7 @@ enqueue_fragment (void *cls, const struct GNUNET_MessageHeader *msg)
825 856
826 udpw = GNUNET_malloc (sizeof (struct UDPMessageWrapper) + msg_len); 857 udpw = GNUNET_malloc (sizeof (struct UDPMessageWrapper) + msg_len);
827 udpw->session = frag_ctx->session; 858 udpw->session = frag_ctx->session;
859 s = udpw->session;
828 udpw->udp = (char *) &udpw[1]; 860 udpw->udp = (char *) &udpw[1];
829 861
830 udpw->msg_size = msg_len; 862 udpw->msg_size = msg_len;
@@ -836,9 +868,48 @@ enqueue_fragment (void *cls, const struct GNUNET_MessageHeader *msg)
836 868
837 enqueue (plugin, udpw); 869 enqueue (plugin, udpw);
838 870
871
872 if (s->addrlen == sizeof (struct sockaddr_in))
873 {
874 if (plugin->with_v4_ws == GNUNET_NO)
875 {
876 if (plugin->select_task != GNUNET_SCHEDULER_NO_TASK)
877 GNUNET_SCHEDULER_cancel(plugin->select_task);
878
879 plugin->select_task =
880 GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
881 GNUNET_SCHEDULER_NO_TASK,
882 GNUNET_TIME_UNIT_FOREVER_REL,
883 plugin->rs_v4,
884 plugin->ws_v4,
885 &udp_plugin_select, plugin);
886 plugin->with_v4_ws = GNUNET_YES;
887 }
888 }
889
890 else if (s->addrlen == sizeof (struct sockaddr_in6))
891 {
892 if (plugin->with_v6_ws == GNUNET_NO)
893 {
894 if (plugin->select_task_v6 != GNUNET_SCHEDULER_NO_TASK)
895 GNUNET_SCHEDULER_cancel(plugin->select_task_v6);
896
897 plugin->select_task_v6 =
898 GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
899 GNUNET_SCHEDULER_NO_TASK,
900 GNUNET_TIME_UNIT_FOREVER_REL,
901 plugin->rs_v6,
902 plugin->ws_v6,
903 &udp_plugin_select_v6, plugin);
904 plugin->with_v6_ws = GNUNET_YES;
905 }
906 }
907
839} 908}
840 909
841 910
911
912
842/** 913/**
843 * Function that can be used by the transport service to transmit 914 * Function that can be used by the transport service to transmit
844 * a message using the plugin. Note that in the case of a 915 * a message using the plugin. Note that in the case of a
@@ -883,6 +954,13 @@ udp_plugin_send (void *cls,
883 GNUNET_assert (plugin != NULL); 954 GNUNET_assert (plugin != NULL);
884 GNUNET_assert (s != NULL); 955 GNUNET_assert (s != NULL);
885 956
957 if ((s->addrlen == sizeof (struct sockaddr_in6)) && (plugin->sockv6 == NULL))
958 return GNUNET_SYSERR;
959
960 if ((s->addrlen == sizeof (struct sockaddr_in)) && (plugin->sockv4 == NULL))
961 return GNUNET_SYSERR;
962
963
886 if (mlen >= GNUNET_SERVER_MAX_MESSAGE_SIZE) 964 if (mlen >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
887 { 965 {
888 GNUNET_break (0); 966 GNUNET_break (0);
@@ -950,6 +1028,43 @@ udp_plugin_send (void *cls,
950 s->frag_ctx = frag_ctx; 1028 s->frag_ctx = frag_ctx;
951 1029
952 } 1030 }
1031
1032 if (s->addrlen == sizeof (struct sockaddr_in))
1033 {
1034 if (plugin->with_v4_ws == GNUNET_NO)
1035 {
1036 if (plugin->select_task != GNUNET_SCHEDULER_NO_TASK)
1037 GNUNET_SCHEDULER_cancel(plugin->select_task);
1038
1039 plugin->select_task =
1040 GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
1041 GNUNET_SCHEDULER_NO_TASK,
1042 GNUNET_TIME_UNIT_FOREVER_REL,
1043 plugin->rs_v4,
1044 plugin->ws_v4,
1045 &udp_plugin_select, plugin);
1046 plugin->with_v4_ws = GNUNET_YES;
1047 }
1048 }
1049
1050 else if (s->addrlen == sizeof (struct sockaddr_in6))
1051 {
1052 if (plugin->with_v6_ws == GNUNET_NO)
1053 {
1054 if (plugin->select_task_v6 != GNUNET_SCHEDULER_NO_TASK)
1055 GNUNET_SCHEDULER_cancel(plugin->select_task_v6);
1056
1057 plugin->select_task_v6 =
1058 GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
1059 GNUNET_SCHEDULER_NO_TASK,
1060 GNUNET_TIME_UNIT_FOREVER_REL,
1061 plugin->rs_v6,
1062 plugin->ws_v6,
1063 &udp_plugin_select_v6, plugin);
1064 plugin->with_v6_ws = GNUNET_YES;
1065 }
1066 }
1067
953 return mlen; 1068 return mlen;
954} 1069}
955 1070
@@ -1648,15 +1763,14 @@ udp_plugin_select (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1648 plugin->select_task = GNUNET_SCHEDULER_NO_TASK; 1763 plugin->select_task = GNUNET_SCHEDULER_NO_TASK;
1649 if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0) 1764 if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0)
1650 return; 1765 return;
1766 plugin->with_v4_ws = GNUNET_NO;
1651 1767
1652 if ((tc->reason & GNUNET_SCHEDULER_REASON_READ_READY) != 0) 1768 if ((tc->reason & GNUNET_SCHEDULER_REASON_READ_READY) != 0)
1653 { 1769 {
1654 if ((NULL != plugin->sockv4) && 1770 if ((NULL != plugin->sockv4) &&
1655 (GNUNET_NETWORK_fdset_isset (tc->read_ready, plugin->sockv4))) 1771 (GNUNET_NETWORK_fdset_isset (tc->read_ready, plugin->sockv4)))
1656 udp_select_read (plugin, plugin->sockv4); 1772 udp_select_read (plugin, plugin->sockv4);
1657 if ((NULL != plugin->sockv6) && 1773
1658 (GNUNET_NETWORK_fdset_isset (tc->read_ready, plugin->sockv6)))
1659 udp_select_read (plugin, plugin->sockv6);
1660 } 1774 }
1661 1775
1662 if ((tc->reason & GNUNET_SCHEDULER_REASON_WRITE_READY) != 0) 1776 if ((tc->reason & GNUNET_SCHEDULER_REASON_WRITE_READY) != 0)
@@ -1666,18 +1780,68 @@ udp_plugin_select (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1666 { 1780 {
1667 udp_select_send (plugin, plugin->sockv4); 1781 udp_select_send (plugin, plugin->sockv4);
1668 } 1782 }
1783 }
1784
1785 if (plugin->select_task != GNUNET_SCHEDULER_NO_TASK)
1786 GNUNET_SCHEDULER_cancel (plugin->select_task);
1787 plugin->select_task = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
1788 GNUNET_SCHEDULER_NO_TASK,
1789 GNUNET_TIME_UNIT_FOREVER_REL,
1790 plugin->rs_v4,
1791 (plugin->ipv4_queue_head != NULL) ? plugin->ws_v4 : NULL,
1792 &udp_plugin_select, plugin);
1793 if (plugin->ipv4_queue_head != NULL)
1794 plugin->with_v4_ws = GNUNET_YES;
1795 else
1796 plugin->with_v4_ws = GNUNET_NO;
1797}
1798
1799
1800/**
1801 * We have been notified that our readset has something to read. We don't
1802 * know which socket needs to be read, so we have to check each one
1803 * Then reschedule this function to be called again once more is available.
1804 *
1805 * @param cls the plugin handle
1806 * @param tc the scheduling context (for rescheduling this function again)
1807 */
1808static void
1809udp_plugin_select_v6 (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1810{
1811 struct Plugin *plugin = cls;
1812
1813 plugin->select_task_v6 = GNUNET_SCHEDULER_NO_TASK;
1814 if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0)
1815 return;
1816
1817 plugin->with_v6_ws = GNUNET_NO;
1818 if ((tc->reason & GNUNET_SCHEDULER_REASON_READ_READY) != 0)
1819 {
1820 if ((NULL != plugin->sockv6) &&
1821 (GNUNET_NETWORK_fdset_isset (tc->read_ready, plugin->sockv6)))
1822 udp_select_read (plugin, plugin->sockv6);
1823 }
1824
1825 if ((tc->reason & GNUNET_SCHEDULER_REASON_WRITE_READY) != 0)
1826 {
1669 if ((NULL != plugin->sockv6) && (plugin->ipv6_queue_head != NULL) && 1827 if ((NULL != plugin->sockv6) && (plugin->ipv6_queue_head != NULL) &&
1670 (GNUNET_NETWORK_fdset_isset (tc->write_ready, plugin->sockv6))) 1828 (GNUNET_NETWORK_fdset_isset (tc->write_ready, plugin->sockv6)))
1671 { 1829 {
1672 udp_select_send (plugin, plugin->sockv6); 1830 udp_select_send (plugin, plugin->sockv6);
1673 } 1831 }
1674 } 1832 }
1675 1833 if (plugin->select_task_v6 != GNUNET_SCHEDULER_NO_TASK)
1676 plugin->select_task = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, 1834 GNUNET_SCHEDULER_cancel (plugin->select_task_v6);
1835 plugin->select_task_v6 = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
1677 GNUNET_SCHEDULER_NO_TASK, 1836 GNUNET_SCHEDULER_NO_TASK,
1678 GNUNET_TIME_UNIT_FOREVER_REL, plugin->rs, 1837 GNUNET_TIME_UNIT_FOREVER_REL,
1679 plugin->ws, &udp_plugin_select, plugin); 1838 plugin->rs_v6,
1680 1839 (plugin->ipv6_queue_head != NULL) ? plugin->ws_v6 : NULL,
1840 &udp_plugin_select_v6, plugin);
1841 if (plugin->ipv6_queue_head != NULL)
1842 plugin->with_v6_ws = GNUNET_YES;
1843 else
1844 plugin->with_v6_ws = GNUNET_NO;
1681} 1845}
1682 1846
1683 1847
@@ -1793,19 +1957,14 @@ setup_sockets (struct Plugin *plugin, struct sockaddr_in6 *serverAddrv6, struct
1793 } 1957 }
1794 1958
1795 /* Create file descriptors */ 1959 /* Create file descriptors */
1796 plugin->rs = GNUNET_NETWORK_fdset_create (); 1960 plugin->rs_v4 = GNUNET_NETWORK_fdset_create ();
1797 plugin->ws = GNUNET_NETWORK_fdset_create (); 1961 plugin->ws_v4 = GNUNET_NETWORK_fdset_create ();
1798 GNUNET_NETWORK_fdset_zero (plugin->rs); 1962 GNUNET_NETWORK_fdset_zero (plugin->rs_v4);
1799 GNUNET_NETWORK_fdset_zero (plugin->ws); 1963 GNUNET_NETWORK_fdset_zero (plugin->ws_v4);
1800 if (NULL != plugin->sockv4) 1964 if (NULL != plugin->sockv4)
1801 { 1965 {
1802 GNUNET_NETWORK_fdset_set (plugin->rs, plugin->sockv4); 1966 GNUNET_NETWORK_fdset_set (plugin->rs_v4, plugin->sockv4);
1803 GNUNET_NETWORK_fdset_set (plugin->ws, plugin->sockv4); 1967 GNUNET_NETWORK_fdset_set (plugin->ws_v4, plugin->sockv4);
1804 }
1805 if (NULL != plugin->sockv6)
1806 {
1807 GNUNET_NETWORK_fdset_set (plugin->rs, plugin->sockv6);
1808 GNUNET_NETWORK_fdset_set (plugin->ws, plugin->sockv6);
1809 } 1968 }
1810 1969
1811 if (sockets_created == 0) 1970 if (sockets_created == 0)
@@ -1814,8 +1973,33 @@ setup_sockets (struct Plugin *plugin, struct sockaddr_in6 *serverAddrv6, struct
1814 plugin->select_task = 1973 plugin->select_task =
1815 GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, 1974 GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
1816 GNUNET_SCHEDULER_NO_TASK, 1975 GNUNET_SCHEDULER_NO_TASK,
1817 GNUNET_TIME_UNIT_FOREVER_REL, plugin->rs, 1976 GNUNET_TIME_UNIT_FOREVER_REL,
1818 plugin->ws, &udp_plugin_select, plugin); 1977 plugin->rs_v4,
1978 NULL,
1979 &udp_plugin_select, plugin);
1980 plugin->with_v4_ws = GNUNET_NO;
1981
1982 if (plugin->enable_ipv6 == GNUNET_YES)
1983 {
1984 plugin->rs_v6 = GNUNET_NETWORK_fdset_create ();
1985 plugin->ws_v6 = GNUNET_NETWORK_fdset_create ();
1986 GNUNET_NETWORK_fdset_zero (plugin->rs_v6);
1987 GNUNET_NETWORK_fdset_zero (plugin->ws_v6);
1988 if (NULL != plugin->sockv6)
1989 {
1990 GNUNET_NETWORK_fdset_set (plugin->rs_v6, plugin->sockv6);
1991 GNUNET_NETWORK_fdset_set (plugin->ws_v6, plugin->sockv6);
1992 }
1993
1994 plugin->select_task_v6 =
1995 GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
1996 GNUNET_SCHEDULER_NO_TASK,
1997 GNUNET_TIME_UNIT_FOREVER_REL,
1998 plugin->rs_v6,
1999 NULL,
2000 &udp_plugin_select_v6, plugin);
2001 plugin->with_v6_ws = GNUNET_NO;
2002 }
1819 2003
1820 plugin->nat = GNUNET_NAT_register (plugin->env->cfg, 2004 plugin->nat = GNUNET_NAT_register (plugin->env->cfg,
1821 GNUNET_NO, plugin->port, 2005 GNUNET_NO, plugin->port,
@@ -2019,6 +2203,11 @@ libgnunet_plugin_transport_udp_done (void *cls)
2019 GNUNET_SCHEDULER_cancel (plugin->select_task); 2203 GNUNET_SCHEDULER_cancel (plugin->select_task);
2020 plugin->select_task = GNUNET_SCHEDULER_NO_TASK; 2204 plugin->select_task = GNUNET_SCHEDULER_NO_TASK;
2021 } 2205 }
2206 if (plugin->select_task_v6 != GNUNET_SCHEDULER_NO_TASK)
2207 {
2208 GNUNET_SCHEDULER_cancel (plugin->select_task_v6);
2209 plugin->select_task_v6 = GNUNET_SCHEDULER_NO_TASK;
2210 }
2022 2211
2023 /* Closing sockets */ 2212 /* Closing sockets */
2024 if (plugin->sockv4 != NULL) 2213 if (plugin->sockv4 != NULL)
@@ -2026,13 +2215,18 @@ libgnunet_plugin_transport_udp_done (void *cls)
2026 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (plugin->sockv4)); 2215 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (plugin->sockv4));
2027 plugin->sockv4 = NULL; 2216 plugin->sockv4 = NULL;
2028 } 2217 }
2218 GNUNET_NETWORK_fdset_destroy (plugin->rs_v4);
2219 GNUNET_NETWORK_fdset_destroy (plugin->ws_v4);
2220
2029 if (plugin->sockv6 != NULL) 2221 if (plugin->sockv6 != NULL)
2030 { 2222 {
2031 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (plugin->sockv6)); 2223 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (plugin->sockv6));
2032 plugin->sockv6 = NULL; 2224 plugin->sockv6 = NULL;
2225
2226 GNUNET_NETWORK_fdset_destroy (plugin->rs_v6);
2227 GNUNET_NETWORK_fdset_destroy (plugin->ws_v6);
2033 } 2228 }
2034 GNUNET_NETWORK_fdset_destroy (plugin->rs); 2229
2035 GNUNET_NETWORK_fdset_destroy (plugin->ws);
2036 GNUNET_NAT_unregister (plugin->nat); 2230 GNUNET_NAT_unregister (plugin->nat);
2037 2231
2038 if (plugin->defrag_ctxs != NULL) 2232 if (plugin->defrag_ctxs != NULL)
diff --git a/src/transport/plugin_transport_udp.h b/src/transport/plugin_transport_udp.h
index 6f78a4169..5637524bc 100644
--- a/src/transport/plugin_transport_udp.h
+++ b/src/transport/plugin_transport_udp.h
@@ -137,6 +137,7 @@ struct Plugin
137 * ID of select task 137 * ID of select task
138 */ 138 */
139 GNUNET_SCHEDULER_TaskIdentifier select_task; 139 GNUNET_SCHEDULER_TaskIdentifier select_task;
140 GNUNET_SCHEDULER_TaskIdentifier select_task_v6;
140 141
141 /** 142 /**
142 * Tokenizer for inbound messages. 143 * Tokenizer for inbound messages.
@@ -166,18 +167,34 @@ struct Plugin
166 /** 167 /**
167 * FD Read set 168 * FD Read set
168 */ 169 */
169 struct GNUNET_NETWORK_FDSet *rs; 170 struct GNUNET_NETWORK_FDSet *rs_v4;
170 171
171 /** 172 /**
172 * FD Write set 173 * FD Write set
173 */ 174 */
174 struct GNUNET_NETWORK_FDSet *ws; 175 struct GNUNET_NETWORK_FDSet *ws_v4;
176
177
178 int with_v4_ws;
175 179
176 /** 180 /**
177 * The read socket for IPv4 181 * The read socket for IPv4
178 */ 182 */
179 struct GNUNET_NETWORK_Handle *sockv4; 183 struct GNUNET_NETWORK_Handle *sockv4;
180 184
185
186 /**
187 * FD Read set
188 */
189 struct GNUNET_NETWORK_FDSet *rs_v6;
190
191 /**
192 * FD Write set
193 */
194 struct GNUNET_NETWORK_FDSet *ws_v6;
195
196 int with_v6_ws;
197
181 /** 198 /**
182 * The read socket for IPv6 199 * The read socket for IPv6
183 */ 200 */