17
17
#include "php_memcached.h"
18
18
#include "php_memcached_private.h"
19
19
#include "php_memcached_server.h"
20
+ #include "php_network.h"
20
21
21
22
#include <event2/listener.h>
22
23
23
- #undef NDEBUG
24
- #undef _NDEBUG
25
24
#include <assert.h>
26
25
27
26
#define MEMC_GET_CB (cb_type ) (MEMC_SERVER_G(callbacks)[cb_type])
@@ -58,9 +57,9 @@ typedef struct {
58
57
static
59
58
long s_invoke_php_callback (php_memc_server_cb_t * cb , zval * params , ssize_t param_count )
60
59
{
61
- zval * retval = NULL ;
60
+ zval retval ;
62
61
63
- cb -> fci .retval = retval ;
62
+ cb -> fci .retval = & retval ;
64
63
cb -> fci .params = params ;
65
64
cb -> fci .param_count = param_count ;
66
65
#if PHP_VERSION_ID < 80000
@@ -73,7 +72,7 @@ long s_invoke_php_callback (php_memc_server_cb_t *cb, zval *params, ssize_t para
73
72
efree (buf );
74
73
}
75
74
76
- return retval == NULL ? PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND : zval_get_long (retval );
75
+ return Z_ISUNDEF ( retval ) ? PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND : zval_get_long (& retval );
77
76
}
78
77
79
78
// memcached protocol callbacks
@@ -96,6 +95,7 @@ protocol_binary_response_status s_add_handler(const void *cookie, const void *ke
96
95
ZVAL_LONG (& zflags , flags );
97
96
ZVAL_LONG (& zexptime , exptime );
98
97
ZVAL_NULL (& zresult_cas );
98
+ ZVAL_MAKE_REF (& zresult_cas );
99
99
100
100
ZVAL_COPY (& params [0 ], & zcookie );
101
101
ZVAL_COPY (& params [1 ], & zkey );
@@ -142,6 +142,7 @@ protocol_binary_response_status s_append_prepend_handler (php_memc_event_t event
142
142
ZVAL_STRINGL (& zvalue , data , data_len );
143
143
ZVAL_DOUBLE (& zcas , cas );
144
144
ZVAL_NULL (& zresult_cas );
145
+ ZVAL_MAKE_REF (& zresult_cas );
145
146
146
147
ZVAL_COPY (& params [0 ], & zcookie );
147
148
ZVAL_COPY (& params [1 ], & zkey );
@@ -198,11 +199,13 @@ protocol_binary_response_status s_incr_decr_handler (php_memc_event_t event, con
198
199
MEMC_MAKE_ZVAL_COOKIE (zcookie , cookie );
199
200
200
201
ZVAL_STRINGL (& zkey , key , key_len );
201
- ZVAL_LONG (& zdelta , (long ) delta );
202
- ZVAL_LONG (& zinital , (long ) initial );
203
- ZVAL_LONG (& zexpiration , (long ) expiration );
202
+ ZVAL_LONG (& zdelta , (zend_long ) delta );
203
+ ZVAL_LONG (& zinital , (zend_long ) initial );
204
+ ZVAL_LONG (& zexpiration , (zend_long ) expiration );
204
205
ZVAL_LONG (& zresult , 0 );
206
+ ZVAL_MAKE_REF (& zresult );
205
207
ZVAL_NULL (& zresult_cas );
208
+ ZVAL_MAKE_REF (& zresult_cas );
206
209
207
210
ZVAL_COPY (& params [0 ], & zcookie );
208
211
ZVAL_COPY (& params [1 ], & zkey );
@@ -296,6 +299,7 @@ protocol_binary_response_status s_flush_handler(const void *cookie, uint32_t whe
296
299
}
297
300
298
301
MEMC_MAKE_ZVAL_COOKIE (zcookie , cookie );
302
+ ZVAL_LONG (& zwhen , when );
299
303
300
304
ZVAL_COPY (& params [0 ], & zcookie );
301
305
ZVAL_COPY (& params [1 ], & zwhen );
@@ -322,6 +326,13 @@ protocol_binary_response_status s_get_handler (const void *cookie, const void *k
322
326
}
323
327
324
328
MEMC_MAKE_ZVAL_COOKIE (zcookie , cookie );
329
+ ZVAL_STRINGL (& zkey , key , key_len );
330
+ ZVAL_NULL (& zvalue );
331
+ ZVAL_MAKE_REF (& zvalue );
332
+ ZVAL_NULL (& zflags );
333
+ ZVAL_MAKE_REF (& zflags );
334
+ ZVAL_NULL (& zresult_cas );
335
+ ZVAL_MAKE_REF (& zresult_cas );
325
336
326
337
ZVAL_COPY (& params [0 ], & zcookie );
327
338
ZVAL_COPY (& params [1 ], & zkey );
@@ -436,11 +447,12 @@ protocol_binary_response_status s_set_replace_handler (php_memc_event_t event, c
436
447
MEMC_MAKE_ZVAL_COOKIE (zcookie , cookie );
437
448
438
449
ZVAL_STRINGL (& zkey , key , key_len );
439
- ZVAL_STRINGL (& zdata , (( char * ) data ), ( int ) data_len );
440
- ZVAL_LONG (& zflags , (long ) flags );
441
- ZVAL_LONG (& zexpiration , (long ) expiration );
450
+ ZVAL_STRINGL (& zdata , data , data_len );
451
+ ZVAL_LONG (& zflags , (zend_long ) flags );
452
+ ZVAL_LONG (& zexpiration , (zend_long ) expiration );
442
453
ZVAL_DOUBLE (& zcas , (double ) cas );
443
454
ZVAL_NULL (& zresult_cas );
455
+ ZVAL_MAKE_REF (& zresult_cas );
444
456
445
457
ZVAL_COPY (& params [0 ], & zcookie );
446
458
ZVAL_COPY (& params [1 ], & zkey );
@@ -494,41 +506,65 @@ protocol_binary_response_status s_stat_handler (const void *cookie, const void *
494
506
{
495
507
zval params [3 ];
496
508
protocol_binary_response_status retval = PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND ;
497
- zval zcookie , zkey , zbody ;
509
+ zval zcookie , zkey , zstats ;
498
510
499
511
if (!MEMC_HAS_CB (MEMC_SERVER_ON_STAT )) {
500
512
return retval ;
501
513
}
502
514
503
515
MEMC_MAKE_ZVAL_COOKIE (zcookie , cookie );
504
516
505
- ZVAL_STRINGL (& zkey , key , key_len );
506
- ZVAL_NULL (& zbody );
517
+ if (key && key_len ) {
518
+ ZVAL_STRINGL (& zkey , key , key_len );
519
+ } else {
520
+ ZVAL_NULL (& zkey );
521
+ }
522
+ array_init (& zstats );
523
+ ZVAL_MAKE_REF (& zstats );
507
524
508
525
ZVAL_COPY (& params [0 ], & zcookie );
509
526
ZVAL_COPY (& params [1 ], & zkey );
510
- ZVAL_COPY (& params [2 ], & zbody );
527
+ ZVAL_COPY (& params [2 ], & zstats );
511
528
512
529
retval = s_invoke_php_callback (& MEMC_GET_CB (MEMC_SERVER_ON_STAT ), params , 3 );
513
530
514
531
if (retval == PROTOCOL_BINARY_RESPONSE_SUCCESS ) {
515
- if (Z_TYPE (zbody ) == IS_NULL ) {
516
- retval = response_handler (cookie , NULL , 0 , NULL , 0 );
532
+ zval * zarray = & zstats ;
533
+ zend_string * key ;
534
+ zend_long idx ;
535
+ zval * val ;
536
+
537
+ ZVAL_DEREF (zarray );
538
+ if (Z_TYPE_P (zarray ) != IS_ARRAY ) {
539
+ convert_to_array (zarray );
517
540
}
518
- else {
519
- if (Z_TYPE (zbody ) != IS_STRING ) {
520
- convert_to_string (& zbody );
541
+
542
+ ZEND_HASH_FOREACH_KEY_VAL (Z_ARRVAL_P (zarray ), idx , key , val )
543
+ {
544
+ zend_string * val_str = zval_get_string (val );
545
+
546
+ if (key ) {
547
+ retval = response_handler (cookie , key -> val , key -> len , val_str -> val , val_str -> len );
548
+ } else {
549
+ char buf [0x20 ], * ptr , * end = & buf [sizeof (buf ) - 1 ];
550
+ ptr = zend_print_long_to_buf (end , idx );
551
+ retval = response_handler (cookie , ptr , end - ptr , val_str -> val , val_str -> len );
552
+ }
553
+ zend_string_release (val_str );
554
+
555
+ if (retval != PROTOCOL_BINARY_RESPONSE_SUCCESS ) {
556
+ break ;
521
557
}
522
- retval = response_handler (cookie , key , key_len , Z_STRVAL (zbody ), (uint32_t ) Z_STRLEN (zbody ));
523
558
}
559
+ ZEND_HASH_FOREACH_END ();
524
560
}
525
561
526
562
zval_ptr_dtor (& params [0 ]);
527
563
zval_ptr_dtor (& params [1 ]);
528
564
zval_ptr_dtor (& params [2 ]);
529
565
zval_ptr_dtor (& zcookie );
530
566
zval_ptr_dtor (& zkey );
531
- zval_ptr_dtor (& zbody );
567
+ zval_ptr_dtor (& zstats );
532
568
return retval ;
533
569
}
534
570
@@ -547,12 +583,12 @@ protocol_binary_response_status s_version_handler (const void *cookie,
547
583
MEMC_MAKE_ZVAL_COOKIE (zcookie , cookie );
548
584
549
585
ZVAL_NULL (& zversion );
586
+ ZVAL_MAKE_REF (& zversion );
550
587
551
588
ZVAL_COPY (& params [0 ], & zcookie );
552
589
ZVAL_COPY (& params [1 ], & zversion );
553
590
554
591
retval = s_invoke_php_callback (& MEMC_GET_CB (MEMC_SERVER_ON_VERSION ), params , 2 );
555
-
556
592
if (retval == PROTOCOL_BINARY_RESPONSE_SUCCESS ) {
557
593
if (Z_TYPE (zversion ) != IS_STRING ) {
558
594
convert_to_string (& zversion );
@@ -581,31 +617,25 @@ void s_handle_memcached_event (evutil_socket_t fd, short what, void *arg)
581
617
582
618
if (!client -> on_connect_invoked ) {
583
619
if (MEMC_HAS_CB (MEMC_SERVER_ON_CONNECT )) {
584
- zval zremoteip , zremoteport ;
585
- zval params [2 ];
620
+ zend_string * zremoteaddr_str ;
621
+ zval zremoteaddr ;
622
+ zval params [1 ];
586
623
protocol_binary_response_status retval ;
587
624
588
- struct sockaddr_in addr_in ;
589
- socklen_t addr_in_len = sizeof (addr_in );
625
+ ZVAL_NULL (& zremoteaddr );
590
626
591
- if (getpeername (fd , (struct sockaddr * ) & addr_in , & addr_in_len ) == 0 ) {
592
- ZVAL_STRING (& zremoteip , inet_ntoa (addr_in .sin_addr ));
593
- ZVAL_LONG (& zremoteport , ntohs (addr_in .sin_port ));
627
+ if (SUCCESS == php_network_get_peer_name (fd , & zremoteaddr_str , NULL , NULL )) {
628
+ ZVAL_STR (& zremoteaddr , zremoteaddr_str );
594
629
} else {
595
630
php_error_docref (NULL , E_WARNING , "getpeername failed: %s" , strerror (errno ));
596
- ZVAL_NULL (& zremoteip );
597
- ZVAL_NULL (& zremoteport );
598
631
}
599
632
600
- ZVAL_COPY (& params [0 ], & zremoteip );
601
- ZVAL_COPY (& params [1 ], & zremoteport );
633
+ ZVAL_COPY (& params [0 ], & zremoteaddr );
602
634
603
- retval = s_invoke_php_callback (& MEMC_GET_CB (MEMC_SERVER_ON_CONNECT ), params , 2 );
635
+ retval = s_invoke_php_callback (& MEMC_GET_CB (MEMC_SERVER_ON_CONNECT ), params , 1 );
604
636
605
637
zval_ptr_dtor (& params [0 ]);
606
- zval_ptr_dtor (& params [1 ]);
607
- zval_ptr_dtor (& zremoteip );
608
- zval_ptr_dtor (& zremoteport );
638
+ zval_ptr_dtor (& zremoteaddr );
609
639
610
640
if (retval != PROTOCOL_BINARY_RESPONSE_SUCCESS ) {
611
641
memcached_protocol_client_destroy (client -> protocol_client );
@@ -714,22 +744,20 @@ php_memc_proto_handler_t *php_memc_proto_handler_new ()
714
744
}
715
745
716
746
static
717
- evutil_socket_t s_create_listening_socket (const char * spec )
747
+ evutil_socket_t s_create_listening_socket (const zend_string * spec )
718
748
{
719
749
evutil_socket_t sock ;
720
750
struct sockaddr_storage addr ;
721
- int addr_len ;
722
-
751
+ socklen_t addr_len ;
723
752
int rc ;
724
753
725
754
addr_len = sizeof (struct sockaddr );
726
- rc = evutil_parse_sockaddr_port (spec , (struct sockaddr * ) & addr , & addr_len );
727
- if (rc != 0 ) {
728
- php_error_docref (NULL , E_WARNING , "Failed to parse bind address" );
755
+ if (SUCCESS != php_network_parse_network_address_with_port (spec -> val , spec -> len , (struct sockaddr * ) & addr , & addr_len )) {
756
+ php_error_docref (NULL , E_WARNING , "Failed to parse bind address: %s" , spec -> val );
729
757
return -1 ;
730
758
}
731
759
732
- sock = socket (AF_INET , SOCK_STREAM , 0 );
760
+ sock = socket (addr . ss_family , SOCK_STREAM , 0 );
733
761
if (sock < 0 ) {
734
762
php_error_docref (NULL , E_WARNING , "socket failed: %s" , strerror (errno ));
735
763
return -1 ;
@@ -770,7 +798,7 @@ evutil_socket_t s_create_listening_socket (const char *spec)
770
798
zend_bool php_memc_proto_handler_run (php_memc_proto_handler_t * handler , zend_string * address )
771
799
{
772
800
struct event * accept_event ;
773
- evutil_socket_t sock = s_create_listening_socket (address -> val );
801
+ evutil_socket_t sock = s_create_listening_socket (address );
774
802
775
803
if (sock == -1 ) {
776
804
return 0 ;
0 commit comments