@@ -3135,3 +3135,91 @@ PHP_FUNCTION(socket_wsaprotocol_info_release)
31353135}
31363136/* }}} */
31373137#endif
3138+
3139+ #ifdef HAVE_CONNECTX
3140+ PHP_FUNCTION (socket_connectx )
3141+ {
3142+ zval * arg1 , * buffers = NULL ;
3143+ php_socket * php_sock ;
3144+ php_addrinfo * ai ;
3145+ zend_long flags = 0 ;
3146+ struct iovec * raw_buffers = NULL ;
3147+ uint32_t raw_buffers_len = 0 ;
3148+ size_t buffers_len = 0 ;
3149+
3150+ ZEND_PARSE_PARAMETERS_START (1 , 3 )
3151+ Z_PARAM_OBJECT_OF_CLASS (arg1 , socket_ce )
3152+ Z_PARAM_OPTIONAL
3153+ Z_PARAM_ARRAY (buffers )
3154+ Z_PARAM_LONG (flags )
3155+ ZEND_PARSE_PARAMETERS_END ();
3156+
3157+ php_sock = Z_SOCKET_P (arg1 );
3158+ ENSURE_SOCKET_VALID (php_sock );
3159+
3160+ if (buffers != NULL) {
3161+ raw_buffers_len = zend_hash_num_elements (Z_ARRVAL_P (buffers ));
3162+ if (raw_buffers_len == 0 ) {
3163+ zend_argument_value_error (3 , "must contain at least one entry" );
3164+ RETURN_THROWS ();
3165+ }
3166+ raw_buffers = emalloc (raw_buffers_len * sizeof (struct iovec ));
3167+ zval * buffer ;
3168+ raw_buffers_len = 0 ;
3169+
3170+ ZEND_HASH_FOREACH_VAL (Z_ARRVAL_P (buffers ), buffer ) {
3171+ if (Z_TYPE_P (buffer ) != IS_STRING ) {
3172+ zend_argument_type_error (2 , "must only have elements of type string, %s given" , zend_zval_value_name (buffer ));
3173+ RETURN_THROWS ();
3174+ }
3175+ const struct iovec vec = {
3176+ .iov_base = (void * )Z_STRVAL_P (buffer ),
3177+ .iov_len = Z_STRLEN_P (buffer )
3178+ };
3179+ raw_buffers [raw_buffers_len ] = vec ;
3180+ raw_buffers_len ++ ;
3181+ } ZEND_HASH_FOREACH_END ();
3182+ }
3183+
3184+ if (flags > 0 && flags & ~(CONNECT_DATA_IDEMPOTENT |CONNECT_RESUME_ON_READ_WRITE )) {
3185+ zend_argument_value_error (4 , "must be CONNECT_DATA_IDEMPOTENT and/or CONNECT_RESUME_ON_READ_WRITE" );
3186+ RETURN_THROWS ();
3187+ }
3188+
3189+ ai = Z_ADDRESS_INFO_P (arg1 );
3190+ // TODO: multiple interfaces support ?
3191+ struct sa_endpoints epoints = {0 };
3192+ epoints .sae_dstaddr = ai -> addrinfo .ai_addr ;
3193+ epoints .sae_dstaddrlen = ai -> addrinfo .ai_addrlen ;
3194+
3195+ // TODO: using final length result ?
3196+ if (connectx (php_sock -> bsd_socket , & epoints , SAE_ASSOCID_ANY , (unsigned int )flags , raw_buffers , raw_buffers_len , & buffers_len , NULL ) < 0 ) {
3197+ efree (raw_buffers );
3198+ PHP_SOCKET_ERROR (php_sock , "Unable to connect" , errno );
3199+ RETURN_FALSE ;
3200+ }
3201+
3202+ efree (raw_buffers );
3203+ RETURN_TRUE ;
3204+ }
3205+
3206+ PHP_FUNCTION (socket_disconnectx )
3207+ {
3208+ zval * arg1 ;
3209+ php_socket * php_sock ;
3210+
3211+ ZEND_PARSE_PARAMETERS_START (1 , 1 )
3212+ Z_PARAM_OBJECT_OF_CLASS (arg1 , socket_ce )
3213+ ZEND_PARSE_PARAMETERS_END ();
3214+
3215+ php_sock = Z_SOCKET_P (arg1 );
3216+ ENSURE_SOCKET_VALID (php_sock );
3217+
3218+ if (disconnectx (php_sock -> bsd_socket , SAE_ASSOCID_ANY , SAE_CONNID_ANY ) < 0 ) {
3219+ PHP_SOCKET_ERROR (php_sock , "Unable to disconnect" , errno );
3220+ RETURN_FALSE ;
3221+ }
3222+
3223+ RETURN_TRUE ;
3224+ }
3225+ #endif
0 commit comments