73
73
74
74
static char ngx_stream_lua_socket_udp_metatable_key ;
75
75
static char ngx_stream_lua_udp_udata_metatable_key ;
76
+ static char ngx_stream_lua_socket_udp_raw_req_socket_metatable_key ;
77
+ static char ngx_stream_lua_socket_udp_downstream_udata_metatable_key ;
76
78
static u_char ngx_stream_lua_socket_udp_buffer [UDP_MAX_DATAGRAM_SIZE ];
77
79
78
80
@@ -84,7 +86,7 @@ ngx_stream_lua_inject_socket_udp_api(ngx_log_t *log, lua_State *L)
84
86
lua_pushcfunction (L , ngx_stream_lua_socket_udp );
85
87
lua_setfield (L , -2 , "udp" ); /* ngx socket */
86
88
87
- /* udp socket object metatable */
89
+ /* udp upstream socket object metatable */
88
90
lua_pushlightuserdata (L , & ngx_stream_lua_socket_udp_metatable_key );
89
91
lua_createtable (L , 0 /* narr */ , 6 /* nrec */ );
90
92
@@ -108,14 +110,41 @@ ngx_stream_lua_inject_socket_udp_api(ngx_log_t *log, lua_State *L)
108
110
lua_rawset (L , LUA_REGISTRYINDEX );
109
111
/* }}} */
110
112
111
- /* udp socket object metatable */
113
+ /* udp downstream socket object metatable */
114
+ lua_pushlightuserdata (L , & ngx_stream_lua_socket_udp_raw_req_socket_metatable_key );
115
+ lua_createtable (L , 0 /* narr */ , 4 /* nrec */ );
116
+
117
+ lua_pushcfunction (L , ngx_stream_lua_socket_udp_send );
118
+ lua_setfield (L , -2 , "send" );
119
+
120
+ lua_pushcfunction (L , ngx_stream_lua_socket_udp_receive );
121
+ lua_setfield (L , -2 , "receive" );
122
+
123
+ lua_pushcfunction (L , ngx_stream_lua_socket_udp_settimeout );
124
+ lua_setfield (L , -2 , "settimeout" ); /* ngx socket mt */
125
+
126
+ lua_pushvalue (L , -1 );
127
+ lua_setfield (L , -2 , "__index" );
128
+ lua_rawset (L , LUA_REGISTRYINDEX );
129
+ /* }}} */
130
+
131
+ /* udp upstream socket object metatable */
112
132
lua_pushlightuserdata (L , & ngx_stream_lua_udp_udata_metatable_key );
113
133
lua_createtable (L , 0 /* narr */ , 1 /* nrec */ ); /* metatable */
114
134
lua_pushcfunction (L , ngx_stream_lua_socket_udp_upstream_destroy );
115
135
lua_setfield (L , -2 , "__gc" );
116
136
lua_rawset (L , LUA_REGISTRYINDEX );
117
137
/* }}} */
118
138
139
+ /* udp downstream socket object metatable */
140
+ lua_pushlightuserdata (L , & ngx_stream_lua_socket_udp_downstream_udata_metatable_key );
141
+ lua_createtable (L , 0 /* narr */ , 1 /* nrec */ ); /* metatable */
142
+ /* share the same destructor as upstream */
143
+ lua_pushcfunction (L , ngx_stream_lua_socket_udp_upstream_destroy );
144
+ lua_setfield (L , -2 , "__gc" );
145
+ lua_rawset (L , LUA_REGISTRYINDEX );
146
+ /* }}} */
147
+
119
148
lua_pop (L , 1 );
120
149
}
121
150
@@ -890,7 +919,7 @@ ngx_stream_lua_socket_udp_send(lua_State *L)
890
919
891
920
dd ("sending query %.*s" , (int ) query .len , query .data );
892
921
893
- n = ngx_send (u -> udp_connection .connection , query .data , query .len );
922
+ n = ngx_udp_send (u -> udp_connection .connection , query .data , query .len );
894
923
895
924
dd ("ngx_send returns %d (query len %d)" , (int ) n , (int ) query .len );
896
925
@@ -988,7 +1017,28 @@ ngx_stream_lua_socket_udp_receive(lua_State *L)
988
1017
ngx_log_debug1 (NGX_LOG_DEBUG_STREAM , r -> connection -> log , 0 ,
989
1018
"lua udp socket receive buffer size: %uz" , u -> recv_buf_size );
990
1019
991
- rc = ngx_stream_lua_socket_udp_read (r , u );
1020
+ if (u -> raw_downstream ) {
1021
+ if (ngx_buf_size (r -> connection -> buffer ) > 0 ) {
1022
+ /* we still have unread data */
1023
+ u -> received = ngx_min ((size_t ) ngx_buf_size (r -> connection -> buffer ),
1024
+ u -> recv_buf_size );
1025
+ ngx_memcpy (ngx_stream_lua_socket_udp_buffer ,
1026
+ r -> connection -> buffer -> pos , u -> received );
1027
+ r -> connection -> buffer -> pos += u -> received ;
1028
+
1029
+ ngx_stream_lua_socket_udp_handle_success (r , u );
1030
+
1031
+ rc = NGX_OK ;
1032
+
1033
+ } else {
1034
+ lua_pushnil (L );
1035
+ lua_pushliteral (L , "no more data" );
1036
+ return 2 ;
1037
+ }
1038
+
1039
+ } else {
1040
+ rc = ngx_stream_lua_socket_udp_read (r , u );
1041
+ }
992
1042
993
1043
if (rc == NGX_ERROR ) {
994
1044
dd ("read failed: %d" , (int ) u -> ft_type );
@@ -1104,7 +1154,11 @@ ngx_stream_lua_socket_udp_finalize(ngx_stream_lua_request_t *r,
1104
1154
u -> resolved -> ctx = NULL ;
1105
1155
}
1106
1156
1107
- if (u -> udp_connection .connection ) {
1157
+ /*
1158
+ * do not close if it is a downstream connection as that will
1159
+ * be handled by stream subsystem itself
1160
+ */
1161
+ if (u -> udp_connection .connection && !u -> raw_downstream ) {
1108
1162
ngx_log_debug0 (NGX_LOG_DEBUG_STREAM , r -> connection -> log , 0 ,
1109
1163
"lua close socket connection" );
1110
1164
@@ -1617,4 +1671,113 @@ ngx_stream_lua_udp_socket_cleanup(void *data)
1617
1671
ngx_stream_lua_socket_udp_finalize (u -> request , u );
1618
1672
}
1619
1673
1674
+
1675
+ int
1676
+ ngx_stream_lua_req_socket_udp (lua_State * L )
1677
+ {
1678
+ ngx_stream_lua_udp_connection_t * pc ;
1679
+ ngx_stream_lua_srv_conf_t * lscf ;
1680
+ ngx_connection_t * c ;
1681
+ ngx_stream_lua_request_t * r ;
1682
+ ngx_stream_lua_ctx_t * ctx ;
1683
+
1684
+ ngx_stream_lua_cleanup_t * cln ;
1685
+ ngx_stream_lua_co_ctx_t * coctx ;
1686
+
1687
+ ngx_stream_lua_socket_udp_upstream_t * u ;
1688
+
1689
+ r = ngx_stream_lua_get_req (L );
1690
+
1691
+ ctx = ngx_stream_lua_get_module_ctx (r , ngx_stream_lua_module );
1692
+ if (ctx == NULL ) {
1693
+ return luaL_error (L , "no ctx found" );
1694
+ }
1695
+
1696
+ ngx_stream_lua_check_context (L , ctx , NGX_STREAM_LUA_CONTEXT_CONTENT
1697
+ |NGX_STREAM_LUA_CONTEXT_PREREAD );
1698
+
1699
+ c = r -> connection ;
1700
+
1701
+ if (c -> buffered ) {
1702
+ lua_pushnil (L );
1703
+ lua_pushliteral (L , "pending data to write" );
1704
+ return 2 ;
1705
+ }
1706
+
1707
+ dd ("ctx acquired raw req socket: %d" , ctx -> acquired_raw_req_socket );
1708
+
1709
+ if (ctx -> acquired_raw_req_socket ) {
1710
+ lua_pushnil (L );
1711
+ lua_pushliteral (L , "duplicate call" );
1712
+ return 2 ;
1713
+ }
1714
+
1715
+ ctx -> acquired_raw_req_socket = 1 ;
1716
+
1717
+ lua_createtable (L , 3 /* narr */ , 1 /* nrec */ ); /* the object */
1718
+ lua_pushlightuserdata (L , & ngx_stream_lua_socket_udp_raw_req_socket_metatable_key );
1719
+ lua_rawget (L , LUA_REGISTRYINDEX );
1720
+ lua_setmetatable (L , -2 );
1721
+
1722
+ u = lua_newuserdata (L , sizeof (ngx_stream_lua_socket_udp_upstream_t ));
1723
+ if (u == NULL ) {
1724
+ return luaL_error (L , "no memory" );
1725
+ }
1726
+
1727
+ #if 1
1728
+ lua_pushlightuserdata (L , & ngx_stream_lua_socket_udp_downstream_udata_metatable_key );
1729
+ lua_rawget (L , LUA_REGISTRYINDEX );
1730
+ lua_setmetatable (L , -2 );
1731
+ #endif
1732
+
1733
+ lua_rawseti (L , 1 , SOCKET_CTX_INDEX );
1734
+
1735
+ ngx_memzero (u , sizeof (ngx_stream_lua_socket_udp_upstream_t ));
1736
+
1737
+ u -> raw_downstream = 1 ;
1738
+
1739
+ coctx = ctx -> cur_co_ctx ;
1740
+
1741
+ u -> request = r ;
1742
+
1743
+ lscf = ngx_stream_lua_get_module_srv_conf (r , ngx_stream_lua_module );
1744
+
1745
+ u -> conf = lscf ;
1746
+
1747
+ u -> read_timeout = u -> conf -> read_timeout ;
1748
+
1749
+ cln = ngx_stream_lua_cleanup_add (r , 0 );
1750
+ if (cln == NULL ) {
1751
+ u -> ft_type |= NGX_STREAM_LUA_SOCKET_FT_ERROR ;
1752
+ lua_pushnil (L );
1753
+ lua_pushliteral (L , "no memory" );
1754
+ return 2 ;
1755
+ }
1756
+
1757
+ cln -> handler = ngx_stream_lua_socket_udp_cleanup ;
1758
+ cln -> data = u ;
1759
+ u -> cleanup = & cln -> handler ;
1760
+
1761
+ pc = & u -> udp_connection ;
1762
+ pc -> log = * c -> log ;
1763
+ pc -> connection = c ;
1764
+
1765
+ dd ("setting data to %p" , u );
1766
+
1767
+ coctx -> data = u ;
1768
+ ctx -> downstream = u ;
1769
+
1770
+ if (c -> read -> timer_set ) {
1771
+ ngx_del_timer (c -> read );
1772
+ }
1773
+
1774
+ if (c -> write -> timer_set ) {
1775
+ ngx_del_timer (c -> write );
1776
+ }
1777
+
1778
+ lua_settop (L , 1 );
1779
+ return 1 ;
1780
+ }
1781
+
1782
+
1620
1783
/* vi:set ft=c ts=4 sw=4 et fdm=marker: */
0 commit comments