/* implement the "debug-ports" and "track-debug-ports" device services */
#include "sysdeps.h"
#define  TRACE_TAG   TRACE_JDWP
#include "adb.h"
#include <errno.h>
#include <stdio.h>
#include <string.h>

/* here's how these things work.

   when adbd starts, it creates a unix server socket
   named @vm-debug-control (@ is a shortcut for "first byte is zero"
   to use the private namespace instead of the file system)

   when a new JDWP daemon thread starts in a new VM process, it creates
   a connection to @vm-debug-control to announce its availability.


     JDWP thread                             @vm-debug-control
         |                                         |
         |------------------------------->         |
         | hello I'm in process <pid>              |
         |                                         |
         |                                         |

    the connection is kept alive. it will be closed automatically if
    the JDWP process terminates (this allows adbd to detect dead
    processes).

    adbd thus maintains a list of "active" JDWP processes. it can send
    its content to clients through the "device:debug-ports" service,
    or even updates through the "device:track-debug-ports" service.

    when a debugger wants to connect, it simply runs the command
    equivalent to  "adb forward tcp:<hostport> jdwp:<pid>"

    "jdwp:<pid>" is a new forward destination format used to target
    a given JDWP process on the device. when sutch a request arrives,
    adbd does the following:

      - first, it calls socketpair() to create a pair of equivalent
        sockets.

      - it attaches the first socket in the pair to a local socket
        which is itself attached to the transport's remote socket:


      - it sends the file descriptor of the second socket directly
        to the JDWP process with the help of sendmsg()


     JDWP thread                             @vm-debug-control
         |                                         |
         |                  <----------------------|
         |           OK, try this file descriptor  |
         |                                         |
         |                                         |

   then, the JDWP thread uses this new socket descriptor as its
   pass-through connection to the debugger (and receives the
   JDWP-Handshake message, answers to it, etc...)

   this gives the following graphics:
                    ____________________________________
                   |                                    |
                   |          ADB Server (host)         |
                   |                                    |
        Debugger <---> LocalSocket <----> RemoteSocket  |
                   |                           ^^       |
                   |___________________________||_______|
                                               ||
                                     Transport ||
           (TCP for emulator - USB for device) ||
                                               ||
                    ___________________________||_______
                   |                           ||       |
                   |          ADBD  (device)   ||       |
                   |                           VV       |
         JDWP <======> LocalSocket <----> RemoteSocket  |
                   |                                    |
                   |____________________________________|

    due to the way adb works, this doesn't need a special socket
    type or fancy handling of socket termination if either the debugger
    or the JDWP process closes the connection.

    THIS IS THE SIMPLEST IMPLEMENTATION I COULD FIND, IF YOU HAPPEN
    TO HAVE A BETTER IDEA, LET ME KNOW - Digit

**********************************************************************/

/** JDWP PID List Support Code
 ** for each JDWP process, we record its pid and its connected socket
 **/

#define  MAX_OUT_FDS   4

#if !ADB_HOST

#include <sys/socket.h>
#include <sys/un.h>

typedef struct JdwpProcess  JdwpProcess;
struct JdwpProcess {
    JdwpProcess*  next;
    JdwpProcess*  prev;
    int           pid;
    int           socket;
    fdevent*      fde;

    char          in_buff[4];  /* input character to read PID */
    int           in_len;      /* number from JDWP process    */

    int           out_fds[MAX_OUT_FDS]; /* output array of file descriptors */
    int           out_count;            /* to send to the JDWP process      */
};

static JdwpProcess  _jdwp_list;

static int
jdwp_process_list( char*  buffer, int  bufferlen )
{
    char*         end  = buffer + bufferlen;
    char*         p    = buffer;
    JdwpProcess*  proc = _jdwp_list.next;

    for ( ; proc != &_jdwp_list; proc = proc->next ) {
        int  len;

        /* skip transient connections */
        if (proc->pid < 0)
            continue;

        len = snprintf(p, end-p, "%d\n", proc->pid);
        if (p + len >= end)
            break;
        p += len;
    }
    p[0] = 0;
    return (p - buffer);
}


static int
jdwp_process_list_msg( char*  buffer, int  bufferlen )
{
    char  head[5];
    int   len = jdwp_process_list( buffer+4, bufferlen-4 );
    snprintf(head, sizeof head, "%04x", len);
    memcpy(buffer, head, 4);
    return len + 4;
}


static void  jdwp_process_list_updated(void);

static void
jdwp_process_free( JdwpProcess*  proc )
{
    if (proc) {
        int  n;

        proc->prev->next = proc->next;
        proc->next->prev = proc->prev;

        if (proc->socket >= 0) {
            shutdown(proc->socket, SHUT_RDWR);
            adb_close(proc->socket);
            proc->socket = -1;
        }

        if (proc->fde != NULL) {
            fdevent_destroy(proc->fde);
            proc->fde = NULL;
        }
        proc->pid = -1;

        for (n = 0; n < proc->out_count; n++) {
            adb_close(proc->out_fds[n]);
        }
        proc->out_count = 0;

        free(proc);

        jdwp_process_list_updated();
    }
}


static void  jdwp_process_event(int, unsigned, void*);  /* forward */


static JdwpProcess*
jdwp_process_alloc( int  socket )
{
    JdwpProcess*  proc = calloc(1,sizeof(*proc));

    if (proc == NULL) {
        D("not enough memory to create new JDWP process\n");
        return NULL;
    }

    proc->socket = socket;
    proc->pid    = -1;
    proc->next   = proc;
    proc->prev   = proc;

    proc->fde = fdevent_create( socket, jdwp_process_event, proc );
    if (proc->fde == NULL) {
        D("could not create fdevent for new JDWP process\n" );
        free(proc);
        return NULL;
    }

    proc->fde->state |= FDE_DONT_CLOSE;
    proc->in_len      = 0;
    proc->out_count   = 0;

    /* append to list */
    proc->next = &_jdwp_list;
    proc->prev = proc->next->prev;

    proc->prev->next = proc;
    proc->next->prev = proc;

    /* start by waiting for the PID */
    fdevent_add(proc->fde, FDE_READ);

    return proc;
}


static void
jdwp_process_event( int  socket, unsigned  events, void*  _proc )
{
    JdwpProcess*  proc = _proc;

    if (events & FDE_READ) {
        if (proc->pid < 0) {
            /* read the PID as a 4-hexchar string */
            char*  p    = proc->in_buff + proc->in_len;
            int    size = 4 - proc->in_len;
            char   temp[5];
            while (size > 0) {
                int  len = recv( socket, p, size, 0 );
                if (len < 0) {
                    if (errno == EINTR)
                        continue;
                    if (errno == EAGAIN)
                        return;
                    /* this can fail here if the JDWP process crashes very fast */
                    D("weird unknown JDWP process failure: %s\n",
                      strerror(errno));

                    goto CloseProcess;
                }
                if (len == 0) {  /* end of stream ? */
                    D("weird end-of-stream from unknown JDWP process\n");
                    goto CloseProcess;
                }
                p            += len;
                proc->in_len += len;
                size         -= len;
            }
            /* we have read 4 characters, now decode the pid */
            memcpy(temp, proc->in_buff, 4);
            temp[4] = 0;

            if (sscanf( temp, "%04x", &proc->pid ) != 1) {
                D("could not decode JDWP %p PID number: '%s'\n", proc, temp);
                goto CloseProcess;
            }

            /* all is well, keep reading to detect connection closure */
            D("Adding pid %d to jdwp process list\n", proc->pid);
            jdwp_process_list_updated();
        }
        else
        {
            /* the pid was read, if we get there it's probably because the connection
             * was closed (e.g. the JDWP process exited or crashed) */
            char  buf[32];

            for (;;) {
                int  len = recv(socket, buf, sizeof(buf), 0);

                if (len <= 0) {
                    if (len < 0 && errno == EINTR)
                        continue;
                    if (len < 0 && errno == EAGAIN)
                        return;
                    else {
                        D("terminating JDWP %d connection: %s\n", proc->pid,
                          strerror(errno));
                        break;
                    }
                }
                else {
                    D( "ignoring unexpected JDWP %d control socket activity (%d bytes)\n",
                       proc->pid, len );
                }
            }

        CloseProcess:
            if (proc->pid >= 0)
                D( "remove pid %d to jdwp process list\n", proc->pid );
            jdwp_process_free(proc);
            return;
        }
    }

    if (events & FDE_WRITE) {
        D("trying to write to JDWP pid controli (count=%d first=%d) %d\n",
          proc->pid, proc->out_count, proc->out_fds[0]);
        if (proc->out_count > 0) {
            int  fd = proc->out_fds[0];
            int  n, ret;
            struct cmsghdr*  cmsg;
            struct msghdr    msg;
            struct iovec     iov;
            char             dummy = '!';
            char             buffer[sizeof(struct cmsghdr) + sizeof(int)];

            iov.iov_base       = &dummy;
            iov.iov_len        = 1;
            msg.msg_name       = NULL;
            msg.msg_namelen    = 0;
            msg.msg_iov        = &iov;
            msg.msg_iovlen     = 1;
            msg.msg_flags      = 0;
            msg.msg_control    = buffer;
            msg.msg_controllen = sizeof(buffer);

            cmsg = CMSG_FIRSTHDR(&msg);
            cmsg->cmsg_len   = msg.msg_controllen;
            cmsg->cmsg_level = SOL_SOCKET;
            cmsg->cmsg_type  = SCM_RIGHTS;
            ((int*)CMSG_DATA(cmsg))[0] = fd;

            for (;;) {
                ret = sendmsg(proc->socket, &msg, 0);
                if (ret >= 0)
                    break;
                if (errno == EINTR)
                    continue;
                D("sending new file descriptor to JDWP %d failed: %s\n",
                  proc->pid, strerror(errno));
                goto CloseProcess;
            }

            D("sent file descriptor %d to JDWP process %d\n",
              fd, proc->pid);

            for (n = 1; n < proc->out_count; n++)
                proc->out_fds[n-1] = proc->out_fds[n];

            if (--proc->out_count == 0)
                fdevent_del( proc->fde, FDE_WRITE );
        }
    }
}


int
create_jdwp_connection_fd(int  pid)
{
    JdwpProcess*  proc = _jdwp_list.next;

    D("looking for pid %d in JDWP process list\n", pid);
    for ( ; proc != &_jdwp_list; proc = proc->next ) {
        if (proc->pid == pid) {
            goto FoundIt;
        }
    }
    D("search failed !!\n");
    return -1;

FoundIt:
    {
        int  fds[2];

        if (proc->out_count >= MAX_OUT_FDS) {
            D("%s: too many pending JDWP connection for pid %d\n",
              __FUNCTION__, pid);
            return -1;
        }

        if (adb_socketpair(fds) < 0) {
            D("%s: socket pair creation failed: %s\n",
              __FUNCTION__, strerror(errno));
            return -1;
        }

        proc->out_fds[ proc->out_count ] = fds[1];
        if (++proc->out_count == 1)
            fdevent_add( proc->fde, FDE_WRITE );

        return fds[0];
    }
}

/**  VM DEBUG CONTROL SOCKET
 **
 **  we do implement a custom asocket to receive the data
 **/

/* name of the debug control Unix socket */
#define  JDWP_CONTROL_NAME      "\0jdwp-control"
#define  JDWP_CONTROL_NAME_LEN  (sizeof(JDWP_CONTROL_NAME)-1)

typedef struct {
    int       listen_socket;
    fdevent*  fde;

} JdwpControl;


static void
jdwp_control_event(int  s, unsigned events, void*  user);


static int
jdwp_control_init( JdwpControl*  control,
                   const char*   sockname,
                   int           socknamelen )
{
    struct sockaddr_un   addr;
    socklen_t            addrlen;
    int                  s;
    int                  maxpath = sizeof(addr.sun_path);
    int                  pathlen = socknamelen;

    if (pathlen >= maxpath) {
        D( "vm debug control socket name too long (%d extra chars)\n",
           pathlen+1-maxpath );
        return -1;
    }

    memset(&addr, 0, sizeof(addr));
    addr.sun_family = AF_UNIX;
    memcpy(addr.sun_path, sockname, socknamelen);

    s = socket( AF_UNIX, SOCK_STREAM, 0 );
    if (s < 0) {
        D( "could not create vm debug control socket. %d: %s\n",
           errno, strerror(errno));
        return -1;
    }

    addrlen = (pathlen + sizeof(addr.sun_family));

    if (bind(s, (struct sockaddr*)&addr, addrlen) < 0) {
        D( "could not bind vm debug control socket: %d: %s\n",
           errno, strerror(errno) );
        adb_close(s);
        return -1;
    }

    if ( listen(s, 4) < 0 ) {
        D("listen failed in jdwp control socket: %d: %s\n",
          errno, strerror(errno));
        adb_close(s);
        return -1;
    }

    control->listen_socket = s;

    control->fde = fdevent_create(s, jdwp_control_event, control);
    if (control->fde == NULL) {
        D( "could not create fdevent for jdwp control socket\n" );
        adb_close(s);
        return -1;
    }

    /* only wait for incoming connections */
    fdevent_add(control->fde, FDE_READ);

    D("jdwp control socket started (%d)\n", control->listen_socket);
    return 0;
}


static void
jdwp_control_event( int  s, unsigned  events, void*  _control )
{
    JdwpControl*  control = (JdwpControl*) _control;

    if (events & FDE_READ) {
        struct sockaddr   addr;
        socklen_t         addrlen = sizeof(addr);
        int               s = -1;
        JdwpProcess*      proc;

        do {
            s = adb_socket_accept( control->listen_socket, &addr, &addrlen );
            if (s < 0) {
                if (errno == EINTR)
                    continue;
                if (errno == ECONNABORTED) {
                    /* oops, the JDWP process died really quick */
                    D("oops, the JDWP process died really quick\n");
                    return;
                }
                /* the socket is probably closed ? */
                D( "weird accept() failed on jdwp control socket: %s\n",
                   strerror(errno) );
                return;
            }
        }
        while (s < 0);

        proc = jdwp_process_alloc( s );
        if (proc == NULL)
            return;
    }
}


static JdwpControl   _jdwp_control;

/** "jdwp" local service implementation
 ** this simply returns the list of known JDWP process pids
 **/

typedef struct {
    asocket  socket;
    int      pass;
} JdwpSocket;

static void
jdwp_socket_close( asocket*  s )
{
    asocket*  peer = s->peer;

    remove_socket(s);

    if (peer) {
        peer->peer = NULL;
        peer->close(peer);
    }
    free(s);
}

static int
jdwp_socket_enqueue( asocket*  s, apacket*  p )
{
    /* you can't write to this asocket */
    put_apacket(p);
    s->peer->close(s->peer);
    return -1;
}


static void
jdwp_socket_ready( asocket*  s )
{
    JdwpSocket*  jdwp = (JdwpSocket*)s;
    asocket*     peer = jdwp->socket.peer;

   /* on the first call, send the list of pids,
    * on the second one, close the connection
    */
    if (jdwp->pass == 0) {
        apacket*  p = get_apacket();
        p->len = jdwp_process_list((char*)p->data, MAX_PAYLOAD);
        peer->enqueue(peer, p);
        jdwp->pass = 1;
    }
    else {
        peer->close(peer);
    }
}

asocket*
create_jdwp_service_socket( void )
{
    JdwpSocket*  s = calloc(sizeof(*s),1);

    if (s == NULL)
        return NULL;

    install_local_socket(&s->socket);

    s->socket.ready   = jdwp_socket_ready;
    s->socket.enqueue = jdwp_socket_enqueue;
    s->socket.close   = jdwp_socket_close;
    s->pass           = 0;

    return &s->socket;
}

/** "track-jdwp" local service implementation
 ** this periodically sends the list of known JDWP process pids
 ** to the client...
 **/

typedef struct JdwpTracker  JdwpTracker;

struct JdwpTracker {
    asocket       socket;
    JdwpTracker*  next;
    JdwpTracker*  prev;
    int           need_update;
};

static JdwpTracker   _jdwp_trackers_list;


static void
jdwp_process_list_updated(void)
{
    char             buffer[1024];
    int              len;
    JdwpTracker*  t = _jdwp_trackers_list.next;

    len = jdwp_process_list_msg(buffer, sizeof(buffer));

    for ( ; t != &_jdwp_trackers_list; t = t->next ) {
        apacket*  p    = get_apacket();
        asocket*  peer = t->socket.peer;
        memcpy(p->data, buffer, len);
        p->len = len;
        peer->enqueue( peer, p );
    }
}

static void
jdwp_tracker_close( asocket*  s )
{
    JdwpTracker*  tracker = (JdwpTracker*) s;
    asocket*      peer    = s->peer;

    if (peer) {
        peer->peer = NULL;
        peer->close(peer);
    }

    remove_socket(s);

    tracker->prev->next = tracker->next;
    tracker->next->prev = tracker->prev;

    free(s);
}

static void
jdwp_tracker_ready( asocket*  s )
{
    JdwpTracker*  t = (JdwpTracker*) s;

    if (t->need_update) {
        apacket*  p = get_apacket();
        t->need_update = 0;
        p->len = jdwp_process_list_msg((char*)p->data, sizeof(p->data));
        s->peer->enqueue(s->peer, p);
    }
}

static int
jdwp_tracker_enqueue( asocket*  s, apacket*  p )
{
    /* you can't write to this socket */
    put_apacket(p);
    s->peer->close(s->peer);
    return -1;
}


asocket*
create_jdwp_tracker_service_socket( void )
{
    JdwpTracker*  t = calloc(sizeof(*t),1);

    if (t == NULL)
        return NULL;

    t->next = &_jdwp_trackers_list;
    t->prev = t->next->prev;

    t->next->prev = t;
    t->prev->next = t;

    install_local_socket(&t->socket);

    t->socket.ready   = jdwp_tracker_ready;
    t->socket.enqueue = jdwp_tracker_enqueue;
    t->socket.close   = jdwp_tracker_close;
    t->need_update    = 1;

    return &t->socket;
}


int
init_jdwp(void)
{
    _jdwp_list.next = &_jdwp_list;
    _jdwp_list.prev = &_jdwp_list;

    _jdwp_trackers_list.next = &_jdwp_trackers_list;
    _jdwp_trackers_list.prev = &_jdwp_trackers_list;

    return jdwp_control_init( &_jdwp_control,
                              JDWP_CONTROL_NAME,
                              JDWP_CONTROL_NAME_LEN );
}

#endif /* !ADB_HOST */

