Browse Source

Added bindto socket context option.

PHP-5.1
Ilia Alshanetsky 21 years ago
parent
commit
b36d4ae02c
  1. 1
      NEWS
  2. 2
      ext/ftp/ftp.c
  3. 34
      main/network.c
  4. 2
      main/php_network.h
  5. 47
      main/streams/xp_socket.c

1
NEWS

@ -1,6 +1,7 @@
PHP NEWS
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
?? Jun 2005, PHP 5.1 Beta 2
- Added bindto socket context option. (Ilia)
- Fixed PDO shutdown problem (possible inifite loop running rollback on
shutdown). (Wez)
- Fixed PECL bug #3714 (beginTransaction doesn't work if you're in

2
ext/ftp/ftp.c

@ -136,7 +136,7 @@ ftp_open(const char *host, short port, long timeout_sec TSRMLS_DC)
ftp->fd = php_network_connect_socket_to_host(host,
(unsigned short) (port ? port : 21), SOCK_STREAM,
0, &tv, NULL, NULL TSRMLS_CC);
0, &tv, NULL, NULL, NULL, 0 TSRMLS_CC);
if (ftp->fd == -1) {
goto bail;
}

34
main/network.c

@ -722,7 +722,7 @@ PHPAPI php_socket_t php_network_accept_incoming(php_socket_t srvsock,
/* {{{ php_network_connect_socket_to_host */
php_socket_t php_network_connect_socket_to_host(const char *host, unsigned short port,
int socktype, int asynchronous, struct timeval *timeout, char **error_string,
int *error_code
int *error_code, char *bindto, unsigned short bindport
TSRMLS_DC)
{
int num_addrs, n, fatal = 0;
@ -785,7 +785,39 @@ php_socket_t php_network_connect_socket_to_host(const char *host, unsigned short
if (sa) {
/* make a connection attempt */
if (bindto) {
struct sockaddr local_address;
if (sa->sa_family == AF_INET) {
struct sockaddr_in *in4 = (struct sockaddr_in*)&local_address;
in4->sin_family = sa->sa_family;
in4->sin_port = htons(bindport);
if (!inet_aton(bindto, &in4->sin_addr)) {
goto bad_ip;
}
bzero(&(in4->sin_zero), 8);
}
#if HAVE_IPV6 && HAVE_INET_PTON
else { /* IPV6 */
struct sockaddr_in6 *in6 = (struct sockaddr_in6*)&local_address;
in6->sin6_family = sa->sa_family;
in6->sin6_port = htons(bindport);
if (inet_pton(AF_INET6, bindto, &in6->sin6_addr) < 1) {
goto bad_ip;
}
}
#endif
if (bind(sock, &local_address, sizeof(struct sockaddr))) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed to bind to '%s:%d', system said: %s", bindto, bindport, strerror(errno));
}
goto bind_done;
bad_ip:
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid IP Address: %s", bindto);
}
bind_done:
n = php_network_connect_socket(sock, sa, socklen, asynchronous,
timeout ? &working_timeout : NULL,
error_string, error_code);

2
main/php_network.h

@ -223,7 +223,7 @@ typedef struct {
BEGIN_EXTERN_C()
PHPAPI php_socket_t php_network_connect_socket_to_host(const char *host, unsigned short port,
int socktype, int asynchronous, struct timeval *timeout, char **error_string,
int *error_code
int *error_code, char *bindto, unsigned short bindport
TSRMLS_DC);
PHPAPI int php_network_connect_socket(php_socket_t sockfd,

47
main/streams/xp_socket.c

@ -487,7 +487,7 @@ static inline int parse_unix_address(php_stream_xport_param *xparam, struct sock
}
#endif
static inline char *parse_ip_address(php_stream_xport_param *xparam, int *portno TSRMLS_DC)
static inline char *parse_ip_address_ex(const char *str, int str_len, int *portno, int get_err, char **err TSRMLS_DC)
{
char *colon;
char *host = NULL;
@ -495,27 +495,27 @@ static inline char *parse_ip_address(php_stream_xport_param *xparam, int *portno
#ifdef HAVE_IPV6
char *p;
if (*(xparam->inputs.name) == '[') {
if (*(str) == '[') {
/* IPV6 notation to specify raw address with port (i.e. [fe80::1]:80) */
p = memchr(xparam->inputs.name + 1, ']', xparam->inputs.namelen - 2);
p = memchr(str + 1, ']', str_len - 2);
if (!p || *(p + 1) != ':') {
if (xparam->want_errortext) {
spprintf(&xparam->outputs.error_text, 0, "Failed to parse IPv6 address \"%s\"", xparam->inputs.name);
if (get_err) {
spprintf(err, 0, "Failed to parse IPv6 address \"%s\"", str);
}
return NULL;
}
*portno = atoi(p + 2);
return estrndup(xparam->inputs.name + 1, p - xparam->inputs.name - 1);
return estrndup(str + 1, p - str - 1);
}
#endif
colon = memchr(xparam->inputs.name, ':', xparam->inputs.namelen - 1);
colon = memchr(str, ':', str_len - 1);
if (colon) {
*portno = atoi(colon + 1);
host = estrndup(xparam->inputs.name, colon - xparam->inputs.name);
host = estrndup(str, colon - str);
} else {
if (xparam->want_errortext) {
spprintf(&xparam->outputs.error_text, 0, "Failed to parse address \"%s\"", xparam->inputs.name);
if (get_err) {
spprintf(err, 0, "Failed to parse address \"%s\"", str);
}
return NULL;
}
@ -523,6 +523,11 @@ static inline char *parse_ip_address(php_stream_xport_param *xparam, int *portno
return host;
}
static inline char *parse_ip_address(php_stream_xport_param *xparam, int *portno TSRMLS_DC)
{
return parse_ip_address_ex(xparam->inputs.name, xparam->inputs.namelen, portno, xparam->want_errortext, &xparam->outputs.error_text);
}
static inline int php_tcp_sockop_bind(php_stream *stream, php_netstream_data_t *sock,
php_stream_xport_param *xparam TSRMLS_DC)
{
@ -572,10 +577,11 @@ static inline int php_tcp_sockop_bind(php_stream *stream, php_netstream_data_t *
static inline int php_tcp_sockop_connect(php_stream *stream, php_netstream_data_t *sock,
php_stream_xport_param *xparam TSRMLS_DC)
{
char *host = NULL;
int portno;
char *host = NULL, *bindto = NULL;
int portno, bindport;
int err;
int ret;
zval **tmpzval = NULL;
#ifdef AF_UNIX
if (stream->ops == &php_stream_unix_socket_ops || stream->ops == &php_stream_unixdg_socket_ops) {
@ -610,6 +616,16 @@ static inline int php_tcp_sockop_connect(php_stream *stream, php_netstream_data_
return -1;
}
if (stream->context && php_stream_context_get_option(stream->context, "socket", "bindto", &tmpzval) == SUCCESS) {
if (Z_TYPE_PP(tmpzval) != IS_STRING) {
if (xparam->want_errortext) {
spprintf(&xparam->outputs.error_text, 0, "local_addr context option is not a string.");
}
return -1;
}
bindto = parse_ip_address_ex(Z_STRVAL_PP(tmpzval), Z_STRLEN_PP(tmpzval), &bindport, xparam->want_errortext, &xparam->outputs.error_text TSRMLS_CC);
}
/* Note: the test here for php_stream_udp_socket_ops is important, because we
* want the default to be TCP sockets so that the openssl extension can
* re-use this code. */
@ -619,7 +635,9 @@ static inline int php_tcp_sockop_connect(php_stream *stream, php_netstream_data_
xparam->op == STREAM_XPORT_OP_CONNECT_ASYNC,
xparam->inputs.timeout,
xparam->want_errortext ? &xparam->outputs.error_text : NULL,
&err
&err,
bindto,
bindport
TSRMLS_CC);
ret = sock->socket == -1 ? -1 : 0;
@ -628,6 +646,9 @@ static inline int php_tcp_sockop_connect(php_stream *stream, php_netstream_data_
if (host) {
efree(host);
}
if (bindto) {
efree(bindto);
}
#ifdef AF_UNIX
out:

Loading…
Cancel
Save