Hi Liviu,

I tried the following and my observations for the same.


1)      Compiled and installed OpenSIPS of 2.2.3 code(no other patches applied).

2)      async(rest_get("https://example.com";<https://example.com>, 
"$var(body)"), resume_route);==> crashes on my machine. Same dump as I shared 
before.

3)      async(rest_get("http://example.com";<%22http:/example.com%22>, 
"$var(body)"), resume_route);==> No crash observed.

4)      Long back I tried to run a sample curl program that will reach 
https://example.com ==> Worked without any crash

5)      I have also tried a sample curl program that interacts with REST server 
(async, https://URL) ==> Worked on the same machine without crash.

Only when the same payload is passed using OpenSIPS, and when processing the 
response of it, OpenSIPS is being crashed.

6)      Tried with async (rest_post(http:// URL)); ==> No crash

7)      Tried with async(rest_post(https://URL)); ==> Crash occurred

I am attaching here with the sample curl file,  where I try to reach 
example.com(getHttps.c) and sample curl program which will do the actual PUT 
request I want to do( asyncPutHttps.c)
With asyncPutHttps.c, whatever I do in the sample program, the same I do 
OpenSIPS too, but not crashing in my sample program and crash occurs only with 
OpenSIPS.

Let me know if you need more information on any of these.

Regards,
Agalya


From: Liviu Chircu [mailto:[email protected]]
Sent: Thursday, March 09, 2017 5:06 AM
To: Ramachandran, Agalya (Contractor) <[email protected]>; 
OpenSIPS users mailling list <[email protected]>
Subject: Re: [OpenSIPS-Users] [RELEASE] OpenSIPS minor releases: 2.2.3 and 
1.11.10


No luck on a CentOS 7.2 system with libcurl 7.29.0 with async rest_get. Some 
more questions:

- does the following crash your system? If not, please detail the nature of 
your HTTP transfer that's causing the crash (server location and a .pcap of a 
successful curl would be nice).

   async(rest_get("https://example.com";<https://example.com>, "$var(body)"), 
resume_route);

- are you using any custom patches for rest_client? I suggest we only use the 
2.2.3 tag code when debugging this issue, from now on

Regards,

Liviu Chircu

OpenSIPS Developer

http://www.opensips-solutions.com



OpenSIPS Summit May 2017 Amsterdam

  http://www.opensips.org/events/Summit-2017Amsterdam.html
On 08.03.2017 18:05, Ramachandran, Agalya (Contractor) wrote:
Hi Liviu,

You got time to reproduce this issue? If you need any help towards it let me 
know.

Regards,
Agalya

/***************************************************************************
 **                                  _   _ ____  _
 **  Project                     ___| | | |  _ \| |
 **                             / __| | | | |_) | |
 **                            | (__| |_| |  _ <| |___
 **                             \___|\___/|_| \_\_____|
 **
 ** Copyright (C) 1998 - 2016, Daniel Stenberg, <[email protected]>, et al.
 **
 ** This software is licensed as described in the file COPYING, which
 ** you should have received as part of this distribution. The terms
 ** are also available at https://curl.haxx.se/docs/copyright.html.
 **
 ** You may opt to use, copy, modify, merge, publish, distribute and/or sell
 ** copies of the Software, and permit persons to whom the Software is
 ** furnished to do so, under the terms of the COPYING file.
 **
 ** This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
 ** KIND, either express or implied.
 **
 ****************************************************************************/ 
/* <DESC>
 ** using the multi interface to do a multipart formpost without blocking
 ** </DESC>
 **/ 
 
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
 
#include <curl/curl.h>
 
int main(void)
{
  CURL *curl;
 
  CURLM *multi_handle;
  int still_running;
 
  struct curl_httppost *formpost=NULL;
  struct curl_httppost *lastptr=NULL;
  struct curl_slist *headerlist=NULL;
  static const char buf[] = "Expect:";
 

  char body[]="{\"Key1\": \"Value1\", \"time\": 1476891582434, \"key3\": 
\"value3\", \"key4\": 
\"value4\",\"Key5\":\"{\\\"test\\\":{\\\"key\\\":\\\"value\\\",\\\"key\\\":\\\"value\\\"},\\\"payload\\\":{\\\"key\\\":\\\"value\\\",\\\"key\\\":\\\"value\\\"}}\"
 }";
  char token[]="sadsd****dsadlkksadl";


  /* Fill in the file upload field. This makes libcurl load data from
 *      the given file name when curl_easy_perform() is called. */ 
/*  curl_formadd(&formpost,
               &lastptr,
               CURLFORM_COPYNAME, "sendfile",
               CURLFORM_FILE, "postit2.c",
               CURLFORM_END);
 */ 
  /* Fill in the filename field */ 
/*  curl_formadd(&formpost,
               &lastptr,
               CURLFORM_COPYNAME, "filename",
               CURLFORM_COPYCONTENTS, "postit2.c",
               CURLFORM_END);
 */
  /* Fill in the submit field too, even if this is rarely needed */ 
/*  curl_formadd(&formpost,
               &lastptr,
               CURLFORM_COPYNAME, "submit",
               CURLFORM_COPYCONTENTS, "send",
               CURLFORM_END);
*/ 
  curl = curl_easy_init();
  multi_handle = curl_multi_init();
 
  /* initialize custom header list (stating that Expect: 100-continue is not
 *      wanted */ 
    //headerlist = curl_slist_append(headerlist, buf);
    headerlist = curl_slist_append(headerlist, "Content-Type: 
application/json");
    char authHeader[255]="Authorization: Bearer ";
    headerlist = curl_slist_append(headerlist, strcat(authHeader, token));

  if(curl && multi_handle) {
 
    /* what URL that receives this POST */ 
    curl_easy_setopt(curl, CURLOPT_URL, "https://URL";);
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, body);

    curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
 
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist);
    //curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);
    curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PUT");
 
    curl_multi_add_handle(multi_handle, curl);
 
    curl_multi_perform(multi_handle, &still_running);

    int i=0; 
    do {
      struct timeval timeout;
      int rc; /* select() return code */ 
      CURLMcode mc; /* curl_multi_fdset() return code */ 
 
      fd_set fdread;
      fd_set fdwrite;
      fd_set fdexcep;
      int maxfd = -1;
 
      long curl_timeo = -1;
 
      FD_ZERO(&fdread);
      FD_ZERO(&fdwrite);
      FD_ZERO(&fdexcep);
 
      /* set a suitable timeout to play around with */ 
      timeout.tv_sec = 1;
      timeout.tv_usec = 0;
 
      curl_multi_timeout(multi_handle, &curl_timeo);
      if(curl_timeo >= 0) {
        timeout.tv_sec = curl_timeo / 1000;
        if(timeout.tv_sec > 1)
          timeout.tv_sec = 1;
        else
          timeout.tv_usec = (curl_timeo % 1000) * 1000;
      }

      printf("curl_timeo = %ld\n", curl_timeo);
      printf("timeout.tv_sec = %ld\n", timeout.tv_sec);
      printf("timeout.tv_usec = %ld\n", timeout.tv_usec);
      timeout.tv_sec = 0;
      timeout.tv_usec = 2000;
 
      /* get file descriptors from the transfers */ 
      mc = curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
 
      if(mc != CURLM_OK) {
        fprintf(stderr, "curl_multi_fdset() failed, code %d.\n", mc);
        break;
      }
 
      /* On success the value of maxfd is guaranteed to be >= -1. We call
           select(maxfd + 1, ...); specially in case of (maxfd == -1) there are
           no fds ready yet so we call select(0, ...) --or Sleep() on Windows--
           to sleep 100ms, which is the minimum suggested value in the
           curl_multi_fdset() doc. */ 
 
      if(maxfd == -1) {
#ifdef _WIN32
        Sleep(100);
        rc = 0;
#else
        /* Portable sleep for platforms other than Windows. */ 
        struct timeval wait = { 0, 100 * 1000 }; /* 100ms */ 
        printf("running: i=[%d] Sleep 100ms\n", i);
        rc = select(0, NULL, NULL, NULL, &wait);
#endif
      }
      else {
        /* Note that on some platforms 'timeout' may be modified by select().
 *            If you need access to the original value save a copy beforehand. 
*/ 
        printf("running: i=[%d] maxfd=[%d]\n", i, maxfd);

        rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
                        int fd;
                        for (fd = 0; fd <= maxfd; fd++) {
                                if (FD_ISSET(fd, &fdread)) {
                                        printf("ongoing transfer on fd %d\n", 
fd);
                                }
                        }

        //rc=0;
      }
 
      switch(rc) {
      case -1:
        /* select error */ 
        break;
      case 0:
      default:
        /* timeout or readable/writable sockets */ 
        printf("multi_perform! i=[%d]\n", i);
        curl_multi_perform(multi_handle, &still_running);
        printf("still_running: %d! i=[%d]\n", still_running, i);
        break;
      }

        struct CURLMsg *m;
 
        /* call curl_multi_perform or curl_multi_socket_action first, then loop
         *    through and check if there are any transfers that have completed 
*/
 
        do {
          int msgq = 0;
          m = curl_multi_info_read(multi_handle, &msgq);
          if(m && (m->msg == CURLMSG_DONE)) {
            CURL *e = m->easy_handle;
            printf("In info_read : i=[%d], msgq=[%d]", i, msgq);             
          }
        } while(m);
  
    i++;

    } while(still_running);
 
    curl_multi_cleanup(multi_handle);
 
    /* always cleanup */ 
    curl_easy_cleanup(curl);
 
    /* then cleanup the formpost chain */ 
    curl_formfree(formpost);
 
    /* free slist */ 
    curl_slist_free_all (headerlist);
  }
  return 0;
}
#include <stdio.h>
#include <curl/curl.h>
 
int main(void)
{
  CURL *curl;
  CURLcode res;
 
  curl_global_init(CURL_GLOBAL_DEFAULT);
 
  curl = curl_easy_init();
  if(curl) {
    curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/";);
 
#ifdef SKIP_PEER_VERIFICATION
    /*
 *      * If you want to connect to a site who isn't using a certificate that is
 *           * signed by one of the certs in the CA bundle you have, you can 
skip the
 *                * verification of the server's certificate. This makes the 
connection
 *                     * A LOT LESS SECURE.
 *                          *
 *                               * If you have a CA cert for the server stored 
someplace else than in the
 *                                    * default bundle, then the CURLOPT_CAPATH 
option might come handy for
 *                                         * you.
 *                                              */ 
    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
#endif
 
#ifdef SKIP_HOSTNAME_VERIFICATION
    /*
 *      * If the site you're connecting to uses a different host name that what
 *           * they have mentioned in their server certificate's commonName (or
 *                * subjectAltName) fields, libcurl will refuse to connect. You 
can skip
 *                     * this check, but this will make the connection less 
secure.
 *                          */ 
    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
#endif
 
    /* Perform the request, res will get the return code */ 
    res = curl_easy_perform(curl);
    /* Check for errors */ 
    if(res != CURLE_OK)
      fprintf(stderr, "curl_easy_perform() failed: %s\n",
              curl_easy_strerror(res));
 
    /* always cleanup */ 
    curl_easy_cleanup(curl);
  }
 
  curl_global_cleanup();
 
  return 0;
}

_______________________________________________
Users mailing list
[email protected]
http://lists.opensips.org/cgi-bin/mailman/listinfo/users

Reply via email to