Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions scripts/mosh.pl
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ BEGIN
my $overwrite = 0;

my $bind_ip = undef;
my $host = undef;

my $use_remote_ip = 'proxy';

Expand Down Expand Up @@ -245,6 +246,7 @@ sub predict_check {
}
$userhost = shift;
@command = @ARGV;
(my $user, $host) = $userhost =~ /^((?:.*@)?)(.*)$/;
if ( not defined $bind_ip or $bind_ip =~ m{^ssh$}i ) {
if ( not defined $localhost ) {
push @bind_arguments, '-s';
Expand Down Expand Up @@ -334,7 +336,7 @@ sub predict_check {
my $ip;
if ( $use_remote_ip eq 'local' ) {
# "parse" the host from what the user gave us
my ($user, $host) = $userhost =~ /^((?:.*@)?)(.*)$/;
(my $user, $host) = $userhost =~ /^((?:.*@)?)(.*)$/;
# get list of addresses
my @res = resolvename( $host, 22, $family );
# Use only the first address as the Mosh IP
Expand Down Expand Up @@ -462,7 +464,7 @@ sub predict_check {
$ENV{ 'MOSH_KEY' } = $key;
$ENV{ 'MOSH_PREDICTION_DISPLAY' } = $predict;
$ENV{ 'MOSH_NO_TERM_INIT' } = '1' if !$term_init;
exec {$client} ("$client", "-# @cmdline |", $ip, $port);
exec {$client} ("$client", "-# @cmdline |", "-n", "$host", $ip, $port);
}

sub shell_quote { join ' ', map {(my $a = $_) =~ s/'/'\\''/g; "'$a'"} @_ }
Expand Down
11 changes: 8 additions & 3 deletions src/frontend/mosh-client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ static void print_usage( FILE* file, const char* argv0 )
{
print_version( file );
fprintf( file,
"\nUsage: %s [-# 'ARGS'] IP PORT\n"
"\nUsage: %s [-# 'ARGS'] [-n hostname] IP PORT\n"
" %s -c\n",
argv0,
argv0 );
Expand Down Expand Up @@ -130,8 +130,10 @@ int main( int argc, char* argv[] )
}
}

char *hostname = NULL;

int opt;
while ( ( opt = getopt( argc, argv, "#:cv" ) ) != -1 ) {
while ( ( opt = getopt( argc, argv, "#:cvn:" ) ) != -1 ) {
switch ( opt ) {
case '#':
// Ignore the original arguments to mosh wrapper
Expand All @@ -143,6 +145,9 @@ int main( int argc, char* argv[] )
case 'v':
verbose++;
break;
case 'n':
hostname = optarg;
break;
default:
print_usage( stderr, argv[0] );
exit( 1 );
Expand Down Expand Up @@ -194,7 +199,7 @@ int main( int argc, char* argv[] )

bool success = false;
try {
STMClient client( ip, desired_port, key.c_str(), predict_mode, verbose, predict_overwrite );
STMClient client( hostname, ip, desired_port, key.c_str(), predict_mode, verbose, predict_overwrite );
client.init();

try {
Expand Down
39 changes: 38 additions & 1 deletion src/frontend/stmclient.cc
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@
#include <sys/ioctl.h>
#include <sys/types.h>
#include <unistd.h>
#include <netdb.h>
#include <sys/socket.h>

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

resume();
} else if ( the_byte == 'r' || the_byte == 'R' ) {
if ( !hostname.empty() ) {
overlays.get_notification_engine().set_notification_string( std::wstring( L"Re-resolving..." ), true );
output_new_frame();
struct addrinfo hints, *res;
memset( &hints, 0, sizeof( hints ) );
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;
int err = getaddrinfo( hostname.c_str(), port.c_str(), &hints, &res );
if ( err == 0 ) {
struct addrinfo *p;
struct addrinfo *match = NULL;
int current_family = net.get_remote_addr().sa.sa_family;

for ( p = res; p != NULL; p = p->ai_next ) {
if ( p->ai_family == current_family ) {
match = p;
break;
}
}

if ( match ) {
net.set_remote_addr( match->ai_addr, match->ai_addrlen );
} else {
net.set_remote_addr( res->ai_addr, res->ai_addrlen );
}

freeaddrinfo( res );
overlays.get_notification_engine().set_notification_string( std::wstring( L"Re-resolved hostname." ), false );
} else {
std::string msg = "DNS failure: ";
msg += gai_strerror( err );
overlays.get_notification_engine().set_notification_string( std::wstring( msg.begin(), msg.end() ), false );
}
}
} else if ( ( the_byte == escape_pass_key ) || ( the_byte == escape_pass_key2 ) ) {
/* Emulation sequence to type escape_key is escape_key +
escape_pass_key (that is escape key without Ctrl) */
Expand Down
13 changes: 8 additions & 5 deletions src/frontend/stmclient.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
class STMClient
{
private:
std::string hostname;
std::string ip;
std::string port;
std::string key;
Expand Down Expand Up @@ -89,16 +90,18 @@ class STMClient
void resume( void ); /* restore state after SIGCONT */

public:
STMClient( const char* s_ip,
STMClient( const char* s_hostname,
const char* s_ip,
const char* s_port,
const char* s_key,
const char* predict_mode,
unsigned int s_verbose,
const char* predict_overwrite )
: ip( s_ip ? s_ip : "" ), port( s_port ? s_port : "" ), key( s_key ? s_key : "" ), escape_key( 0x1E ),
escape_pass_key( '^' ), escape_pass_key2( '^' ), escape_requires_lf( false ), escape_key_help( L"?" ),
saved_termios(), raw_termios(), window_size(), local_framebuffer( 1, 1 ), new_state( 1, 1 ), overlays(),
network(), display( true ) /* use TERM environment var to initialize display */, connecting_notification(),
: hostname( s_hostname ? s_hostname : "" ), ip( s_ip ? s_ip : "" ), port( s_port ? s_port : "" ),
key( s_key ? s_key : "" ), escape_key( 0x1E ), escape_pass_key( '^' ), escape_pass_key2( '^' ),
escape_requires_lf( false ), escape_key_help( L"?" ), saved_termios(), raw_termios(), window_size(),
local_framebuffer( 1, 1 ), new_state( 1, 1 ), overlays(), network(),
display( true ) /* use TERM environment var to initialize display */, connecting_notification(),
repaint_requested( false ), lf_entered( false ), quit_sequence_started( false ), clean_shutdown( false ),
verbose( s_verbose )
{
Expand Down
18 changes: 18 additions & 0 deletions src/network/network.cc
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,24 @@ Connection::Connection( const char* key_str, const char* ip, const char* port )
set_MTU( remote_addr.sa.sa_family );
}

void Connection::set_remote_addr( const struct sockaddr* addr, socklen_t len )
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a little skeptical of of this impl (I think I want to unconditionally push a new Socket onto socks), but this does work as written. I'll revisit this later

{
fatal_assert( len <= sizeof( remote_addr ) );

bool family_changed = ( remote_addr.sa.sa_family != addr->sa_family );

remote_addr_len = len;
memcpy( &remote_addr.sa, addr, remote_addr_len );

has_remote_addr = true;

if ( family_changed ) {
socks.push_back( Socket( remote_addr.sa.sa_family ) );
}

set_MTU( remote_addr.sa.sa_family );
}

void Connection::send( const std::string& s )
{
if ( !has_remote_addr ) {
Expand Down
1 change: 1 addition & 0 deletions src/network/network.h
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,7 @@ class Connection

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

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

Expand Down
1 change: 1 addition & 0 deletions src/network/networktransport.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ class Transport

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

std::string& get_send_error( void ) { return connection.get_send_error(); }
};
Expand Down
Loading