Skip to content

Commit 0f7fb52

Browse files
committed
Allow manual re-resolving of server hostname
1 parent decd9b7 commit 0f7fb52

7 files changed

Lines changed: 78 additions & 11 deletions

File tree

scripts/mosh.pl

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ BEGIN
6969
my $overwrite = 0;
7070

7171
my $bind_ip = undef;
72+
my $host = undef;
7273

7374
my $use_remote_ip = 'proxy';
7475

@@ -245,6 +246,7 @@ sub predict_check {
245246
}
246247
$userhost = shift;
247248
@command = @ARGV;
249+
(my $user, $host) = $userhost =~ /^((?:.*@)?)(.*)$/;
248250
if ( not defined $bind_ip or $bind_ip =~ m{^ssh$}i ) {
249251
if ( not defined $localhost ) {
250252
push @bind_arguments, '-s';
@@ -334,7 +336,7 @@ sub predict_check {
334336
my $ip;
335337
if ( $use_remote_ip eq 'local' ) {
336338
# "parse" the host from what the user gave us
337-
my ($user, $host) = $userhost =~ /^((?:.*@)?)(.*)$/;
339+
(my $user, $host) = $userhost =~ /^((?:.*@)?)(.*)$/;
338340
# get list of addresses
339341
my @res = resolvename( $host, 22, $family );
340342
# Use only the first address as the Mosh IP
@@ -462,7 +464,7 @@ sub predict_check {
462464
$ENV{ 'MOSH_KEY' } = $key;
463465
$ENV{ 'MOSH_PREDICTION_DISPLAY' } = $predict;
464466
$ENV{ 'MOSH_NO_TERM_INIT' } = '1' if !$term_init;
465-
exec {$client} ("$client", "-# @cmdline |", $ip, $port);
467+
exec {$client} ("$client", "-# @cmdline |", "-n", "$host", $ip, $port);
466468
}
467469

468470
sub shell_quote { join ' ', map {(my $a = $_) =~ s/'/'\\''/g; "'$a'"} @_ }

src/frontend/mosh-client.cc

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ static void print_usage( FILE* file, const char* argv0 )
8585
{
8686
print_version( file );
8787
fprintf( file,
88-
"\nUsage: %s [-# 'ARGS'] IP PORT\n"
88+
"\nUsage: %s [-# 'ARGS'] [-n hostname] IP PORT\n"
8989
" %s -c\n",
9090
argv0,
9191
argv0 );
@@ -126,8 +126,10 @@ int main( int argc, char* argv[] )
126126
}
127127
}
128128

129+
char *hostname = NULL;
130+
129131
int opt;
130-
while ( ( opt = getopt( argc, argv, "#:cv" ) ) != -1 ) {
132+
while ( ( opt = getopt( argc, argv, "#:cvn:" ) ) != -1 ) {
131133
switch ( opt ) {
132134
case '#':
133135
// Ignore the original arguments to mosh wrapper
@@ -139,6 +141,9 @@ int main( int argc, char* argv[] )
139141
case 'v':
140142
verbose++;
141143
break;
144+
case 'n':
145+
hostname = optarg;
146+
break;
142147
default:
143148
print_usage( stderr, argv[0] );
144149
exit( 1 );
@@ -190,7 +195,7 @@ int main( int argc, char* argv[] )
190195

191196
bool success = false;
192197
try {
193-
STMClient client( ip, desired_port, key.c_str(), predict_mode, verbose, predict_overwrite );
198+
STMClient client( hostname, ip, desired_port, key.c_str(), predict_mode, verbose, predict_overwrite );
194199
client.init();
195200

196201
try {

src/frontend/stmclient.cc

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@
4545
#include <sys/ioctl.h>
4646
#include <sys/types.h>
4747
#include <unistd.h>
48+
#include <netdb.h>
49+
#include <sys/socket.h>
4850

4951
#if HAVE_PTY_H
5052
#include <pty.h>
@@ -193,7 +195,7 @@ void STMClient::init( void )
193195
tmp = std::string( escape_key_name_buf );
194196
std::wstring escape_key_name = std::wstring( tmp.begin(), tmp.end() );
195197
escape_key_help
196-
= L"Commands: Ctrl-Z suspends, \".\" quits, " + escape_pass_name + L" gives literal " + escape_key_name;
198+
= L"Commands: Ctrl-Z suspends, \".\" quits, \"r\" forces a re-resolve, " + escape_pass_name + L" gives literal " + escape_key_name;
197199
overlays.get_notification_engine().set_escape_key_string( tmp );
198200
}
199201
wchar_t tmp[128];
@@ -367,6 +369,41 @@ bool STMClient::process_user_input( int fd )
367369
kill( 0, SIGSTOP );
368370

369371
resume();
372+
} else if ( the_byte == 'r' || the_byte == 'R' ) {
373+
if ( !hostname.empty() ) {
374+
overlays.get_notification_engine().set_notification_string( std::wstring( L"Re-resolving..." ), true );
375+
output_new_frame();
376+
struct addrinfo hints, *res;
377+
memset( &hints, 0, sizeof( hints ) );
378+
hints.ai_family = AF_UNSPEC;
379+
hints.ai_socktype = SOCK_DGRAM;
380+
int err = getaddrinfo( hostname.c_str(), port.c_str(), &hints, &res );
381+
if ( err == 0 ) {
382+
struct addrinfo *p;
383+
struct addrinfo *match = NULL;
384+
int current_family = net.get_remote_addr().sa.sa_family;
385+
386+
for ( p = res; p != NULL; p = p->ai_next ) {
387+
if ( p->ai_family == current_family ) {
388+
match = p;
389+
break;
390+
}
391+
}
392+
393+
if ( match ) {
394+
net.set_remote_addr( match->ai_addr, match->ai_addrlen );
395+
} else {
396+
net.set_remote_addr( res->ai_addr, res->ai_addrlen );
397+
}
398+
399+
freeaddrinfo( res );
400+
overlays.get_notification_engine().set_notification_string( std::wstring( L"Re-resolved hostname." ), false );
401+
} else {
402+
std::string msg = "DNS failure: ";
403+
msg += gai_strerror( err );
404+
overlays.get_notification_engine().set_notification_string( std::wstring( msg.begin(), msg.end() ), false );
405+
}
406+
}
370407
} else if ( ( the_byte == escape_pass_key ) || ( the_byte == escape_pass_key2 ) ) {
371408
/* Emulation sequence to type escape_key is escape_key +
372409
escape_pass_key (that is escape key without Ctrl) */

src/frontend/stmclient.h

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
class STMClient
4848
{
4949
private:
50+
std::string hostname;
5051
std::string ip;
5152
std::string port;
5253
std::string key;
@@ -89,16 +90,18 @@ class STMClient
8990
void resume( void ); /* restore state after SIGCONT */
9091

9192
public:
92-
STMClient( const char* s_ip,
93+
STMClient( const char* s_hostname,
94+
const char* s_ip,
9395
const char* s_port,
9496
const char* s_key,
9597
const char* predict_mode,
9698
unsigned int s_verbose,
9799
const char* predict_overwrite )
98-
: ip( s_ip ? s_ip : "" ), port( s_port ? s_port : "" ), key( s_key ? s_key : "" ), escape_key( 0x1E ),
99-
escape_pass_key( '^' ), escape_pass_key2( '^' ), escape_requires_lf( false ), escape_key_help( L"?" ),
100-
saved_termios(), raw_termios(), window_size(), local_framebuffer( 1, 1 ), new_state( 1, 1 ), overlays(),
101-
network(), display( true ) /* use TERM environment var to initialize display */, connecting_notification(),
100+
: hostname( s_hostname ? s_hostname : "" ), ip( s_ip ? s_ip : "" ), port( s_port ? s_port : "" ),
101+
key( s_key ? s_key : "" ), escape_key( 0x1E ), escape_pass_key( '^' ), escape_pass_key2( '^' ),
102+
escape_requires_lf( false ), escape_key_help( L"?" ), saved_termios(), raw_termios(), window_size(),
103+
local_framebuffer( 1, 1 ), new_state( 1, 1 ), overlays(), network(),
104+
display( true ) /* use TERM environment var to initialize display */, connecting_notification(),
102105
repaint_requested( false ), lf_entered( false ), quit_sequence_started( false ), clean_shutdown( false ),
103106
verbose( s_verbose )
104107
{

src/network/network.cc

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,24 @@ Connection::Connection( const char* key_str, const char* ip, const char* port )
364364
set_MTU( remote_addr.sa.sa_family );
365365
}
366366

367+
void Connection::set_remote_addr( const struct sockaddr* addr, socklen_t len )
368+
{
369+
fatal_assert( len <= sizeof( remote_addr ) );
370+
371+
bool family_changed = ( remote_addr.sa.sa_family != addr->sa_family );
372+
373+
remote_addr_len = len;
374+
memcpy( &remote_addr.sa, addr, remote_addr_len );
375+
376+
has_remote_addr = true;
377+
378+
if ( family_changed ) {
379+
socks.push_back( Socket( remote_addr.sa.sa_family ) );
380+
}
381+
382+
set_MTU( remote_addr.sa.sa_family );
383+
}
384+
367385
void Connection::send( const std::string& s )
368386
{
369387
if ( !has_remote_addr ) {

src/network/network.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,7 @@ class Connection
233233

234234
const Addr& get_remote_addr( void ) const { return remote_addr; }
235235
socklen_t get_remote_addr_len( void ) const { return remote_addr_len; }
236+
void set_remote_addr( const struct sockaddr* addr, socklen_t len );
236237

237238
std::string& get_send_error( void ) { return send_error; }
238239

src/network/networktransport.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ class Transport
126126

127127
const Addr& get_remote_addr( void ) const { return connection.get_remote_addr(); }
128128
socklen_t get_remote_addr_len( void ) const { return connection.get_remote_addr_len(); }
129+
void set_remote_addr( const struct sockaddr* addr, socklen_t len ) { connection.set_remote_addr( addr, len ); }
129130

130131
std::string& get_send_error( void ) { return connection.get_send_error(); }
131132
};

0 commit comments

Comments
 (0)