same time enable real-time state notification
of future state transitions.
-The output format consists of 4 comma-separated parameters:
+The output format consists of up to 9 comma-separated parameters:
(a) the integer unix date/time,
(b) the state name,
(c) optional descriptive string (used mostly on RECONNECTING
and EXITING to show the reason for the disconnect),
- (d) optional TUN/TAP local IP address (shown for ASSIGN_IP
- and CONNECTED), and
- (e) optional address of remote server (OpenVPN 2.1 or higher).
+ (d) optional TUN/TAP local IPv4 address
+ (e) optional address of remote server,
+ (f) optional port of remote server,
+ (g) optional local address,
+ (h) optional local port, and
+ (i) optional TUN/TAP local IPv6 address.
+
+Fields (e)-(h) are shown for CONNECTED state,
+(d) and (i) are shown for ASSIGN_IP and CONNECTED states.
+
+(e) is available starting from OpenVPN 2.1
+(f)-(i) are available starting from OpenVPN 2.4
Real-time state notifications will have a ">STATE:" prefix
prepended to them.
management_set_state (management,
OPENVPN_STATE_GET_CONFIG,
NULL,
- 0,
- 0);
+ NULL,
+ NULL,
+ NULL,
+ NULL);
}
#endif
/* fire up push request right away (already 1s delayed) */
#include "ping.h"
#include "mstats.h"
#include "ssl_verify.h"
+#include "forward-inline.h"
#include "memdbg.h"
/* Tell management interface that we initialized */
if (management)
{
- in_addr_t tun_local = 0;
- in_addr_t tun_remote = 0; /* FKS */
+ in_addr_t *tun_local = NULL;
+ struct in6_addr *tun_local6 = NULL;
+ struct openvpn_sockaddr local, remote;
+ struct link_socket_actual *actual;
+ socklen_t sa_len = sizeof(local);
const char *detail = "SUCCESS";
- if (c->c1.tuntap)
- tun_local = c->c1.tuntap->local;
- /* TODO(jjo): for ipv6 this will convert some 32bits in the ipv6 addr
- * to a meaningless ipv4 address.
- * In any case, is somewhat inconsistent to send local tunnel
- * addr with remote _endpoint_ addr (?)
- */
- tun_remote = htonl (c->c1.link_socket_addr.actual.dest.addr.in4.sin_addr.s_addr);
if (flags & ISC_ERRORS)
- detail = "ERROR";
+ detail = "ERROR";
+
+ CLEAR (local);
+ actual = &get_link_socket_info(c)->lsa->actual;
+ remote = actual->dest;
+ getsockname(c->c2.link_socket->sd, &local.addr.sa, &sa_len);
+#if ENABLE_IP_PKTINFO
+ if (!addr_defined(&local))
+ {
+ switch (local.addr.sa.sa_family)
+ {
+ case AF_INET:
+ local.addr.in4.sin_addr = actual->pi.in4.ipi_spec_dst;
+ break;
+ case AF_INET6:
+ local.addr.in6.sin6_addr = actual->pi.in6.ipi6_addr;
+ break;
+ }
+ }
+#endif
+
+ if (c->c1.tuntap)
+ {
+ tun_local = &c->c1.tuntap->local;
+ tun_local6 = &c->c1.tuntap->local_ipv6;
+ }
management_set_state (management,
OPENVPN_STATE_CONNECTED,
detail,
tun_local,
- tun_remote);
+ tun_local6,
+ &local,
+ &remote);
if (tun_local)
- management_post_tunnel_open (management, tun_local);
+ management_post_tunnel_open (management, *tun_local);
}
#endif
}
management_set_state (management,
OPENVPN_STATE_CONNECTING,
NULL,
- (in_addr_t)0,
- (in_addr_t)0);
+ NULL,
+ NULL,
+ NULL,
+ NULL);
}
/* initial management hold, called early, before first context initialization */
management_set_state (struct management *man,
const int state,
const char *detail,
- const in_addr_t tun_local_ip,
- const in_addr_t tun_remote_ip)
+ const in_addr_t *tun_local_ip,
+ const struct in6_addr *tun_local_ip6,
+ const struct openvpn_sockaddr *local,
+ const struct openvpn_sockaddr *remote)
{
if (man->persist.state && (!(man->settings.flags & MF_SERVER) || state < OPENVPN_STATE_CLIENT_BASE))
{
e.timestamp = now;
e.u.state = state;
e.string = detail;
- e.local_ip = tun_local_ip;
- e.remote_ip = tun_remote_ip;
-
+ if (tun_local_ip)
+ e.local_ip = *tun_local_ip;
+ if (tun_local_ip6)
+ e.local_ip6 = *tun_local_ip6;
+ if (local)
+ e.local_sock = *local;
+ if (remote)
+ e.remote_sock = *remote;
+
log_history_add (man->persist.state, &e);
if (man->connection.state_realtime)
if (flags & LOG_PRINT_LOCAL_IP)
buf_printf (&out, ",%s", print_in_addr_t (e->local_ip, IA_EMPTY_IF_UNDEF, gc));
if (flags & LOG_PRINT_REMOTE_IP)
- buf_printf (&out, ",%s", print_in_addr_t (e->remote_ip, IA_EMPTY_IF_UNDEF, gc));
+ {
+ buf_printf (&out, ",%s", (!addr_defined (&e->remote_sock) ? "," :
+ print_sockaddr_ex (&e->remote_sock.addr.sa, ",", PS_DONT_SHOW_FAMILY|PS_SHOW_PORT, gc)));
+ buf_printf (&out, ",%s", (!addr_defined (&e->local_sock) ? "," :
+ print_sockaddr_ex (&e->local_sock.addr.sa, ",", PS_DONT_SHOW_FAMILY|PS_SHOW_PORT, gc)));
+ }
+ if (flags & LOG_PRINT_LOCAL_IP && !IN6_IS_ADDR_UNSPECIFIED(&e->local_ip6))
+ buf_printf (&out, ",%s", print_in6_addr (e->local_ip6, IA_EMPTY_IF_UNDEF, gc));
if (flags & LOG_ECHO_TO_LOG)
msg (D_MANAGEMENT, "MANAGEMENT: %s", BSTR (&out));
if (flags & LOG_PRINT_CRLF)
time_t timestamp;
const char *string;
in_addr_t local_ip;
- in_addr_t remote_ip;
+ struct in6_addr local_ip6;
+ struct openvpn_sockaddr local_sock;
+ struct openvpn_sockaddr remote_sock;
union log_entry_union u;
};
void management_set_state (struct management *man,
const int state,
const char *detail,
- const in_addr_t tun_local_ip,
- const in_addr_t tun_remote_ip);
+ const in_addr_t *tun_local_ip,
+ const struct in6_addr *tun_local_ip6,
+ const struct openvpn_sockaddr *local_addr,
+ const struct openvpn_sockaddr *remote_addr);
/*
* The management object keeps track of OpenVPN --echo
management_set_state (management,
OPENVPN_STATE_ADD_ROUTES,
NULL,
- 0,
- 0);
+ NULL,
+ NULL,
+ NULL,
+ NULL);
}
#endif
management_set_state (management,
state,
si->signal_text ? si->signal_text : signal_name (si->signal_received, true),
- (in_addr_t)0,
- (in_addr_t)0);
+ NULL,
+ NULL,
+ NULL,
+ NULL);
}
#endif
}
management_set_state (management,
OPENVPN_STATE_RESOLVE,
NULL,
- (in_addr_t)0,
- (in_addr_t)0);
+ NULL,
+ NULL,
+ NULL,
+ NULL);
}
#endif
management_set_state (management,
OPENVPN_STATE_TCP_CONNECT,
NULL,
- (in_addr_t)0,
- (in_addr_t)0);
+ NULL,
+ NULL,
+ NULL,
+ NULL);
#endif
/* Set the actual address */
switch(sa->sa_family)
{
case AF_INET:
- buf_puts (&out, "[AF_INET]");
+ if (!(flags & PS_DONT_SHOW_FAMILY))
+ buf_puts (&out, "[AF_INET]");
salen = sizeof (struct sockaddr_in);
addr_is_defined = ((struct sockaddr_in*) sa)->sin_addr.s_addr != 0;
break;
case AF_INET6:
- buf_puts (&out, "[AF_INET6]");
+ if (!(flags & PS_DONT_SHOW_FAMILY))
+ buf_puts (&out, "[AF_INET6]");
salen = sizeof (struct sockaddr_in6);
addr_is_defined = !IN6_IS_ADDR_UNSPECIFIED(&((struct sockaddr_in6*) sa)->sin6_addr);
break;
case AF_UNSPEC:
- return "[AF_UNSPEC]";
+ if (!(flags & PS_DONT_SHOW_FAMILY))
+ return "[AF_UNSPEC]";
+ else
+ return "";
default:
ASSERT(0);
}
#define PS_SHOW_PORT (1<<1)
#define PS_SHOW_PKTINFO (1<<2)
#define PS_DONT_SHOW_ADDR (1<<3)
+#define PS_DONT_SHOW_FAMILY (1<<4)
const char *print_sockaddr_ex (const struct sockaddr *addr,
const char* separator,
management_set_state (management,
OPENVPN_STATE_WAIT,
NULL,
- 0,
- 0);
+ NULL,
+ NULL,
+ NULL,
+ NULL);
}
#endif
}
management_set_state (management,
OPENVPN_STATE_AUTH,
NULL,
- 0,
- 0);
+ NULL,
+ NULL,
+ NULL,
+ NULL);
}
#endif
management_set_state (management,
OPENVPN_STATE_ASSIGN_IP,
NULL,
- tt->local,
- 0);
+ &tt->local,
+ &tt->local_ipv6,
+ NULL,
+ NULL);
}
#endif