After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 693738 - gtk print dialog shows "Getting printer information failed" for cups remote printer
gtk print dialog shows "Getting printer information failed" for cups remote p...
Status: RESOLVED FIXED
Product: gtk+
Classification: Platform
Component: Printing
2.18.x
Other Linux
: Normal major
: ---
Assigned To: gtk-bugs
gtk-bugs
Depends on:
Blocks:
 
 
Reported: 2013-02-13 20:14 UTC by Rui Gouveia
Modified: 2015-05-13 10:35 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Print Dialog with error (34.63 KB, image/png)
2013-02-13 20:14 UTC, Rui Gouveia
  Details
Check connection to remote CUPS server on correct port (gtk+-2.24 version) (4.26 KB, patch)
2014-07-11 09:46 UTC, Marek Kašík
committed Details | Review
Check connection to remote CUPS server on correct port (gtk master version) (4.14 KB, patch)
2014-07-11 09:46 UTC, Marek Kašík
committed Details | Review

Description Rui Gouveia 2013-02-13 20:14:28 UTC
Created attachment 235949 [details]
Print Dialog with error

Description of problem:

All the GTK applications are hitting in the bug:

"Getting printer information failed" in the Print Dialog

Other applications work.


Version-Release number of selected component (if applicable):
cups-1.4.2-48.el6_3.3.x86_64
gtk2-2.18.9-10.el6.x86_64


How reproducible:
Always.


Steps to Reproduce:
1. Install a Print Server (RHEL6.3).
2. Install a Client (RHEL6.3)
3. Try to print in a GTK application. For example, Firefox, gnome-help or gimp. (with others it works).

  
Actual results:

The client can see the shared printers, but the Print Dialog has the Print button disabled and the message is "Getting printer information failed".


Expected results:

No error. The button is enabled and printing is possible.


Additional info:

The lpoptions appear well defined. The printer is accessible at "printer-uri-supported=ipp://192.168.122.99:63101/printers/HP-LaserJet-5200" :

# lpoptions 
auth-info-required=none copies=1 device-uri=ipp://192.168.122.99:63101/printers/HP-LaserJet-5200 job-hold-until=no-hold job-priority=50 marker-change-time=1360357008 marker-colors=none marker-levels=24 marker-names='Black Cartridge HP Q7516A' marker-types=tonerCartridge number-up=1 printer-info='HP LaserJet 5200' printer-is-accepting-jobs=true printer-is-shared=false printer-location='GSS 2' printer-make-and-model='HP LaserJet 5200 Postscript (recommended) on 192.168.122.99' printer-state=3 printer-state-change-time=1360356574 printer-state-reasons=none printer-type=27439302 printer-uri-supported=ipp://192.168.122.99:63101/printers/HP-LaserJet-5200


But strace shows that the port number is ignored and the default ipp port is used instead :

2665  connect(22, {sa_family=AF_INET, sin_port=htons(631), sin_addr=inet_addr("192.168.122.99")}, 16) = -1 EINPROGRESS (Operation now in progress)
2665  connect(22, {sa_family=AF_INET, sin_port=htons(631), sin_addr=inet_addr("192.168.122.99")}, 16) = -1 ECONNREFUSED (Connection refused)
2665  close(22)                         = 0


The following is a tcpdump from the server side :

# tcpdump -nn -v -i any host 192.168.122.228
tcpdump: listening on any, link-type LINUX_SLL (Linux cooked), capture size 65535 bytes
19:15:56.413416 IP (tos 0x0, ttl 64, id 52810, offset 0, flags [DF], proto TCP (6), length 60)
    192.168.122.228.50929 > 192.168.122.99.631: Flags [S], cksum 0x1a9c (correct), seq 2187211175, win 14600, options [mss 1460,sackOK,TS val 6815725 ecr 0,nop,wscale 7], length 0
19:15:56.413462 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 40)
    192.168.122.99.631 > 192.168.122.228.50929: Flags [R.], cksum 0xbbc8 (correct), seq 0, ack 2187211176, win 0, length 0
19:16:06.240436 IP (tos 0x0, ttl 64, id 55959, offset 0, flags [DF], proto TCP (6), length 209)


Has a workaround, if the server also listens on port 631, everything works as expected.


Thank you
Comment 1 Rui Gouveia 2013-08-21 12:56:28 UTC
Hi,

I did more testes regarding this issue, suspecting a wrong configuration, but I just confirmed the issue.

Server has in cupsd.conf:

  Port 63101
  BrowsePort 63101

Client has cupsd.conf:

  BrowsePoll 192.168.122.99:63101
  BrowsePort 63101


Firewall allows traffic:

7    ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           state NEW tcp dpt:63101 
8    ACCEPT     udp  --  0.0.0.0/0            0.0.0.0/0           state NEW udp dpt:63101 

SELinux allows the non-standaard port 63101 in the server and the client:

# semanage port -l | grep ipp
ipp_port_t                     tcp      63101, 631, 8610-8614
ipp_port_t                     udp      63101, 631, 8610-8614


All the non-Gtk application work as expected, using only the port 63101/tcp and udp, but when the Gtk Print Dialog starts the following communications is attempted and fails:

20:24:33.886932 IP 192.168.122.228.52755 > 192.168.122.99.631: Flags [S], seq 1291153458, win 14600, options [mss 1460,sackOK,TS val 5593038 ecr 0,nop,wscale 7], length 0
20:24:33.887248 IP 192.168.122.99.631 > 192.168.122.228.52755: Flags [R.], seq 0, ack 1291153459, win 0, length 0

I tried setting the IPP_PORT Env variable without success.

Looking at the source code, I noticed that the Gtk platform when connecting to the cups server uses always the Cups API function "ippPort()" :

      request->http = httpConnectEncrypt (request->server, 
                                          ippPort (), 
                                          cupsEncryption ());



Looking at the ippPort definition in gtk+-2.18.9/modules/printbackends/cups/gtkcupsutils.c :


######################
int                                     /* O - Port number */
ippPort(void)
{
  _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */


  DEBUG_puts("ippPort()");

  if (!cg->ipp_port)
    _cupsSetDefaults();

  DEBUG_printf(("1ippPort: Returning %d...", cg->ipp_port));

  return (cg->ipp_port);
}
#######################


It's not clear what port the function is really returning, but it must be in the library globals:



Any thoughts ?

Thank you

Best regards,
Rui Gouveia
Red Hat UK, GSS
Comment 2 Rui Gouveia 2013-08-21 13:02:17 UTC
Hello again,

The function _cupsSetDefaults in cups-1.4.2/cups/usersys.c is:

#######################
/*
* '_cupsSetDefaults()' - Set the default server, port, and encryption.
 */

void
_cupsSetDefaults(void)
{
  cups_file_t   *fp;                    /* File */
  const char    *home,                  /* Home directory of user */
                *cups_encryption,       /* CUPS_ENCRYPTION env var */
                *cups_server;           /* CUPS_SERVER env var */
  char          filename[1024];         /* Filename */
  _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */


  DEBUG_puts("_cupsSetDefaults()");

 /*
* First collect environment variables...
  */

  cups_encryption = getenv("CUPS_ENCRYPTION");
  cups_server     = getenv("CUPS_SERVER");

 /*
* Then, if needed, the .cups/client.conf or .cupsrc file in the home
* directory...
  */

  if ((cg->encryption == (http_encryption_t)-1 || !cg->server[0] ||
       !cg->ipp_port) && (home = getenv("HOME")) != NULL)
  {
   /*
	* Look for ~/.cups/client.conf or ~/.cupsrc...
    */

    snprintf(filename, sizeof(filename), "%s/.cups/client.conf", home);
    if ((fp = cupsFileOpen(filename, "r")) == NULL)
    {
      snprintf(filename, sizeof(filename), "%s/.cupsrc", home);
      fp = cupsFileOpen(filename, "r");
    }

    if (fp)
    {
      cups_read_client_conf(fp, cg, cups_encryption, cups_server);
      cupsFileClose(fp);
    }
  }

  if (cg->encryption == (http_encryption_t)-1 || !cg->server[0] ||
      !cg->ipp_port)
  {
   /*
	* Look for CUPS_SERVERROOT/client.conf...
    */

    snprintf(filename, sizeof(filename), "%s/client.conf", cg->cups_serverroot);
    if ((fp = cupsFileOpen(filename, "r")) != NULL)
    {
      cups_read_client_conf(fp, cg, cups_encryption, cups_server);
      cupsFileClose(fp);
    }
  }

 /*
* If we still have things that aren't set, use the compiled in defaults...
  */

  if (cg->encryption == (http_encryption_t)-1)
    cg->encryption = HTTP_ENCRYPT_IF_REQUESTED;

  if (!cg->server[0])
  {
    if (!cups_server)
    {
#ifdef CUPS_DEFAULT_DOMAINSOCKET
     /*
	* If we are compiled with domain socket support, only use the
	* domain socket if it exists and has the right permissions...
      */

      struct stat       sockinfo;       /* Domain socket information */

      if (!stat(CUPS_DEFAULT_DOMAINSOCKET, &sockinfo) &&
          (sockinfo.st_mode & S_IRWXO) == S_IRWXO)
        cups_server = CUPS_DEFAULT_DOMAINSOCKET;
      else
#endif /* CUPS_DEFAULT_DOMAINSOCKET */
      cups_server = "localhost";
    }

    cupsSetServer(cups_server);
  }

  if (!cg->ipp_port)
  {
    const char          *ipp_port;      /* IPP_PORT environment variable */
    struct servent      *service;       /* Port number info */  


    if ((ipp_port = getenv("IPP_PORT")) != NULL)
    {
      if ((cg->ipp_port = atoi(ipp_port)) <= 0)
        cg->ipp_port = CUPS_DEFAULT_IPP_PORT;
    }
    else if ((service = getservbyname("ipp", NULL)) == NULL ||
             service->s_port <= 0)
      cg->ipp_port = CUPS_DEFAULT_IPP_PORT;
    else
      cg->ipp_port = ntohs(service->s_port);
  }
}
#######################


If I define the ENV vars: IPP_PORT and CUPS_SERVER it works!!! :)

Since the server is parsed correctly, the problem must be in the port selection. Agree?

Thank you

Best regards,
Rui Gouveia
Red Hat UK, GSS
Comment 3 Rui Gouveia 2013-08-21 13:21:04 UTC
Looking at the function _cupsSetDefaults(void)...

Since the server is parsed correctly, the problem must be in the port
selection. Correct me if I'm wrong.

### If cg->ipp_port is not defined

  if (!cg->ipp_port)
  {
    const char          *ipp_port;      /* IPP_PORT environment variable */
    struct servent      *service;       /* Port number info */  

### ipp_port takes the value from ENV(IPP_PORT) and is not null.

    if ((ipp_port = getenv("IPP_PORT")) != NULL)
    {

### If conversion from string to integer generates an
### error cg->ipp_port takes the default value CUPS_DEFAULT_IPP_PORT

      if ((cg->ipp_port = atoi(ipp_port)) <= 0)
        cg->ipp_port = CUPS_DEFAULT_IPP_PORT;
    }

### else, if ipp does not exists in the system services
### or service->s_port has an invalid value, then
### cg->ipp_port takes the default value CUPS_DEFAULT_IPP_PORT

    else if ((service = getservbyname("ipp", NULL)) == NULL ||
             service->s_port <= 0)
      cg->ipp_port = CUPS_DEFAULT_IPP_PORT;

### else, cg->ipp_port takes the value of the services value.

    else
      cg->ipp_port = ntohs(service->s_port);
  }


So, if IPP_PORT is defined, all is ok, but if not, this code jumps directly to getting the default value in services.

So, where is the value in the configuration read ? I may be analyzing the wrong code here...

Help is appreciated.


Thank you

Best regards,
Rui Gouveia
Red Hat UK, GSS
Comment 4 Marek Kašík 2014-07-11 09:46:24 UTC
Created attachment 280493 [details] [review]
Check connection to remote CUPS server on correct port (gtk+-2.24 version)

The problem is that the connection test connects always to standard port provided by ippPort(). It should connect to the port taken from uri of the remote printer instead. The attached patch solves the problem by adding a parameter for specification of the port to gtk_cups_connection_cups_new() and by specifying the port where needed.
Comment 5 Marek Kašík 2014-07-11 09:46:46 UTC
Created attachment 280494 [details] [review]
Check connection to remote CUPS server on correct port (gtk master version)
Comment 6 Matthias Clasen 2015-03-31 15:09:35 UTC
Review of attachment 280494 [details] [review]:

makes sense to me. please put this on the 3.16 and 3.14 branches too
Comment 7 Matthias Clasen 2015-03-31 15:09:38 UTC
Review of attachment 280494 [details] [review]:

makes sense to me. please put this on the 3.16 and 3.14 branches too
Comment 8 Matthias Clasen 2015-03-31 15:10:00 UTC
Review of attachment 280493 [details] [review]:

ok.
Comment 9 Michael Catanzaro 2015-04-17 15:15:15 UTC
Did these patches get lost?
Comment 10 Marek Kašík 2015-05-13 10:35:40 UTC
Thank you for the review.
I wasn't added to CC when I've attached the patch so I missed the Matthias' review.
I've pushed the patch to 2.24, 3.14, 3.16 and master.